【codeforces】Codeforces Round #523 (Div. 2)
目錄
【B. Views Matter】
題目連結:https://codeforces.com/contest/1061/problem/B
【題意】有一堆塊,給出每個的高度ai,給出俯檢視和右檢視,從原來的堆中最多可以取出多少塊使得俯檢視和右檢視均保持不變。並且題中規定物體是不受重力影響的,即拿掉之後是不會有物塊進行移動的。
【分析】貪心。將物塊按高度由高到低排序,記錄初始高度。ans初值是n,即要先滿足俯檢視。k由1開始,如果當前k<當前塊高度,那麼k++,一直到k達到最大高度n,此時右檢視已經滿足,break掉就好。
【程式碼】
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+10; int a[maxn]; int main() { ll n,m;scanf("%lld%lld",&n,&m); ll sum=0; for(ll i=0;i<n;i++) { scanf("%lld",&a[i]); sum+=a[i]; } sort(a,a+n); ll ans=n,k=1; for(int i=0;i<n;i++) { if(k<=a[i])k++; if(k>a[n-1])break; } ans=ans+a[n-1]-k+1; printf("%lld\n",sum-ans); return 0; }
【C. Multiplicity】dp+滾動陣列
題目連結:https://codeforces.com/contest/1061/problem/C
【題目】長度為n的序列,移除一些元素之後使之成為“good array”(對於其下標i總滿足a[i]%i==0)
【分析】dp[i][j]:選擇前i個元素組成的序列中長度為j的滿足題意的方案數;
因為題上資料範圍比較大,1e5,所以開二維陣列會爆記憶體的
所以,要用到滾動陣列———是一種節省空間的辦法,時間上貌似沒有什麼優勢,多用於DP中
上述遞推關係式中,第一維中每次只用到了i和i-1,我們壓縮第一維,
那麼dp[x]中的x就相當於上式中的j,得下式:
dp[x]=dp[x]+dp[x-1];
dp[x]表示長度為x的合法子序列的個數;
每次dp[x]在未更新前存的相當於是上面遞推式中的dp[i-1][j],dp[x-1]就相當於dp[i-1][j-1],理解一下— —
【程式碼】
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
const int mod=1e9+7;
typedef long long ll;
ll dp[maxn],a[maxn];
vector<int>v[maxn];
int main()
{
ll n;scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
{
ll now=sqrt(a[i]);
for(int j=1;j<=now;j++)
{
if(a[i]%j==0)
{
v[i].push_back(j);
if(a[i]!=j*j) v[i].push_back(a[i]/j);//存2次,但防止了有兩個相同因子的數進2次
}
}
sort(v[i].begin(),v[i].end());
}
dp[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=v[i].size()-1;j>=0;j--)
{
int now=v[i][j];
dp[now]+=dp[now-1];
dp[now]%=mod;
}
}
ll ans=0;
for(int i=1;i<=n;i++)ans+=dp[i];
ans%=mod;
printf("%lld\n",ans);
return 0;
}
【D. TV Shows】
題目連結:https://codeforces.com/contest/1061/problem/D
【題意】給出n個節目的開始時間與結束時間,給出租每臺TV的花費以及租了之後每分鐘的花費。求放映完所有節目的最小花費。
【分析】貪心。先把n個節目排序,是否再租一臺電腦取決於這段時間的花費與x的大小。用set和map,map存同一結束時間的節目數,當某個值為0時表示這個點結束的節目都已放映完。set存每個節目的結束時間。
emmm感覺是個思維題,暫時可能不會想到這麼做,程式碼也理解了好一會...
【程式碼】參考https://blog.csdn.net/qq_39826163/article/details/84649678
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const ll mod=1e9+7;
struct node{
ll l,r;
}a[maxn];
bool cmp(node x,node y)
{
return x.l!=y.l?x.l<y.l:x.r<y.r;
}
set<ll>s;
set<ll>::iterator it;
map<ll,int>mp;
int main()
{
int n; ll x,y;
scanf("%d%lld%lld",&n,&x,&y);
for(int i=0;i<n;i++)scanf("%lld%lld",&a[i].l,&a[i].r);
sort(a,a+n,cmp);
ll ans=0;
s.insert(a[0].r);
mp[a[0].r]++;
ans=(ans+x+y*(a[0].r-a[0].l)%mod)%mod;
for(int i=1;i<n;i++)
{
it=s.lower_bound(a[i].l);//大於等於當前開始時間的結束時間
if(it==s.begin())//沒找到
{
ans=(ans+x+y*(a[i].r-a[i].l)%mod)%mod;
mp[a[i].r]++;
}
else
{
it--;
ll value=*it;
if(a[i].l>value && y*(a[i].l-value)<=x)
{
mp[value]--;
if(mp[value]==0)s.erase(value);
ans=(ans+y*(a[i].r-value)%mod)%mod;
mp[a[i].r]++;
}
else
{
ans=(ans+x+y*(a[i].r-a[i].l)%mod)%mod;
mp[a[i].r]++;
}
}
s.insert(a[i].r);
}
printf("%lld\n",ans);
return 0;
}