题目抽象:CD的容量为N,M首歌,每首歌的大小为v,问将哪些歌曲刻在CD上,可以使得CD上没使用的空间最小。
分析:01背包,倒着选择,以便输出。另开一个二维数组记录状态转移时的策略。
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=10010;
int f[maxn],cost[maxn];
bool g[25][maxn];
int main()
{
int n,V;
while(scanf("%d",&V)==1){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&cost[i]);
memset(f,0,sizeof(f));
memset(g,false,sizeof(g));
for(int i=n;i>=1;i--){
for(int v=V;v>=cost[i];v--){
if(f[v]<f[v-cost[i]]+cost[i]){
g[i][v]=true;
f[v]=f[v-cost[i]]+cost[i];
}
}
}
int v=V;
for(int i=1;i<=n;i++){
if(g[i][v]){
printf("%d ",cost[i]);
v-=cost[i];
}
}
printf("sum:%d\n",f[V]);
}
return 0;
}