[南海云课堂] [贪心] [问题转换] [DP] 盘子
洛谷链接,题意一样。
题意
小明家举行聚会,邀请了很多同学参加,所以小明准备了很多盘子,装水果共同学们吃,由于来的同学比较多,所以小明不得不把果盘合并到一起,这样就可以腾出来很多盘子。
小明准备了n个盘子,每个盘子上面放了
请你帮小明算一下最少需要多少个盘子才能装的下所有的水果,以及该情况下所用的最少时间。
思路
注意第二问是建立在第一问的基础上的。
对于第一问,简单的贪心,从大到小取盘子即可,在此不过多赘述。
对于第二问,我们发现没必要将所有盘子上的水果都移动,固定住一些盘子,将其它水果转移至上面即可,这样做一定更优于前者。
那么时间花费便是:
于是问题被转换为求
首先有前两位
总结起来就是
容量、价值......这不就是个
转移方程便是
时间复杂度为
考试硬写题的后果是状态都不对,这个故事告诉我们要先从题目性质入手分析,死磕不一定能对。
代码
细节不算多,就只放
//as、bs:a数组、b数组之和
for(int i=1; i<=n;i++){
for(int j=i; j>=1;j--){
for(int k=bs; k>=0;k--){
if(k>=c[i].b){ //合法状态才可转移
f[j][k]=max(f[j][k],f[j-1][k-c[i].b]+c[i].an);
}
}
}
}
for(int k=as; k<=1e4+5;k++){
ans2=min(ans2,as-f[ans1][k]);
}
cout<<ans1<<' '<<ans2;