链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=311
这道题是完全背包的一个变型,,:求的是把背包装满的最优解.
dp方程跟经典的一样:
for(i=0; i<m; i++) for(j=c[i]; j<=v; j++) { if(dp[j-c[i]]+w[i]>dp[j]) dp[j]=dp[j-c[i]]+w[i]; }
不同的是,这里要把除dp[0]外的所有值初始化为无穷小,dp[0]=0;
这样,在第一次循环中:只要当 j-c[0]==0时,才能给dp[j]赋值...:dp[c[0]]=w[0];,,然后当j-c[0]==c[0],,,再赋值:dp[c[0]]=w[0]+w[0].................实现一个物品可以选多次
#include <iostream> #include<cstring> using namespace std; int c[2005],w[2005]; int dp[50005]; int main() { int n; cin>>n; int i,j; int m,v; while(n--) { cin>>m>>v; memset(dp,-100,sizeof(dp)); //初始化为无穷小 dp[0]=0; for(i=0;i<m;i++) cin>>c[i]>>w[i]; for(i=0; i<m; i++) for(j=c[i]; j<=v; j++) { if(dp[j-c[i]]+w[i]>dp[j]) dp[j]=dp[j-c[i]]+w[i]; } if(dp[v]<0) cout<<"NO"<<endl; else cout<<dp[v]<<endl; } return 0; }