目录
【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;
}