HDU2639 Bone Collector 2.0
题目链接
可知题目要求输出所有解中第K优的解
解法:动态规划求第K优解
传统的动态规划方程为f[i][j]=max(f[i-1][j],f[i-1][j-a[i]]+b[i]),可知因为max只取其中较大的一个,因此我们会遗漏部分解,而要输出第k优解应将其所有的解按递减顺序不重复的储存起来,所以我们需重新考虑动态规划方程。以物品数为阶段,对应体积为状态,我们增加一维即f[i][j][k]表示物品数为i体积为j时的第k优解,那么我们可将f[i][j]理解为由k个解组成的有序序列,可知f[i][j]序列即由f[i-1][j]序列与f[i][j-a[i]]+b[i]序列归并排列得到;
我们可得出状态转移方程:f[i][j](1~k)=merge(f[i-1][j](1~k),f[i-1][j-a[i]]+b[i](1~k));
#include#include using namespace std; int h[105],v[105],a[105],b[105],dp[1005][35]; int main(){ int n,m,k,s; cin>>s; while(s--){ cin>>n>>m>>k; memset(dp,0,sizeof(dp)); for(int i=0;i >h[i]; for(int i=0;i >v[i]; for(int i=0;i =v[i];j--){ for(int f=1;f<=k;f++){ a[f]=dp[j][f]; b[f]=dp[j-v[i]][f]+h[i]; } a[k+1]=-1;b[k+1]=-1; int t=1,c=1,d=1; while(t<=k&&(c<=k||d<=k)){ if(a[c]>b[d]) { dp[j][t]=a[c]; c++; } else { dp[j][t]=b[d]; d++; } if(dp[j][t]!=dp[j][t-1]) t++ } } cout<