这道题是根据01背包转化而来的。
1、01背包是从 V 到c[i](逆序),完全背包是从c[i] 到 V (顺序),决策的方向不一样,过程就不一样,结果就不一样(01背包、完全背包、多重背包)
2、还有就是背包是否恰好装满这一条件,恰好装满,不必恰好装满。
3、这道题里的负无穷表示方式 “1<<7” (基础)
背包恰好装满:完全背包
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[50005],c[100005],w[100005];
int main()
{
//freopen("完全背包.txt","r",stdin);
int n,m,v,i,j;
cin>>n;
while(n--){
cin>>m>>v;
memset(c,0,sizeof(c));
memset(w,0,sizeof(w));
memset(dp,1<<7,sizeof(dp));
dp[0]=0;
for(i=1;i<=m;i++)
cin>>c[i]>>w[i];
for(i=1;i<=m;i++){
for(j=c[i];j<=v;j++)
dp[j]=dp[j]>dp[j-c[i]]+w[i]? dp[j]:dp[j-c[i]]+w[i];
}
if(dp[v]>0)
cout<<dp[v]<<endl;
else
cout<<"NO"<<endl;
//for(i=1;i<=v;i++)
//cout<<dp[i]<<" ";
}
return 0;
}
背包恰好装满改进版(主要在空间上)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[50005];
int main()
{
//freopen("完全背包.txt","r",stdin);
int n,m,v,c,w,i,j;
cin>>n;
while(n--){
cin>>m>>v;
memset(dp,1<<7,sizeof(dp)); //背包恰好装满且求最 大 值,则dp[]除了dp[0]初始化为0外,其他的初始化为 负 无穷
dp[0]=0; //背包恰好装满且求最 小 值,则dp[]除了dp[0]初始化为0外,其他的初始化为 正 无穷
for(i=0;i<m;i++){
cin>>c>>w;
for(j=c;j<=v;j++)
dp[j]=dp[j]>dp[j-c]+w? dp[j]:dp[j-c]+w;
}
if(dp[v]>0)
cout<<dp[v]<<endl;
else
cout<<"NO"<<endl;
//for(i=1;i<=v;i++)
//cout<<dp[i]<<" ";
}
return 0;
}
背包不必恰好装满(跟01背包差不多,但是也得顺序决策)
#include<iostream>
#include<cstdio>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[50005];
int main()
{
freopen("完全背包.txt","r",stdin);
int n,m,v,c,w,i,j;
cin>>n;
while(n--){
cin>>m>>v;
memset(dp,0,sizeof(dp)); //不必恰好装满的话,dp[]全部初始化为 0
//dp[0]=0;
for(i=0;i<m;i++){
cin>>c>>w;
for(j=c;j<=v;j++) //顺序决策
dp[j]=dp[j]>dp[j-c]+w? dp[j]:dp[j-c]+w;
}
cout<<dp[v]<<endl;
}
return 0;
}