NYOJ 311 完全背包

链接: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;
}


 

你可能感兴趣的:(背包)