poj 3624 Charm Bracelet (01背包 水题)
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int dp[1600005];
int v[3500],w[3500];
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int n,vv;
while(scanf("%d%d",&n,&vv)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d%d",&v[i],&w[i]);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
for(int j=vv;j>=v[i];j--)
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
printf("%d\n",dp[vv]);
}
return 0;
}
hdu 1864 最大报销额 (01背包)
由于数组下标不能是double 型,所以把所有的报销费用扩大一百倍进行递推。
值得吐糟的是:数组要开到3*10^7那么大,题目给的是每张报销额度不超过1000,发票最多30张,按理
dp[]开到30*1000+10就够了,我本来出于保险还扩大了10倍,还是re。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[3000010]; //数组一定要开这么大,否则RE
int v[31];
int main()
{
int n,m,flag,r;
char t;
double tmp,s1,s2,s3,a,sum;
while(scanf("%lf%d",&sum,&n)!=EOF)
{
if(n==0)break;
flag=0;r=0;
for(int i=1;i<=n;i++)
{
s1=s2=s3=0;
scanf("%d",&m);
for(int j=1;j<=m;j++)
{
scanf(" %c:%lf",&t,&a);
if(t!='A'&& t!='B'&&t!='C')
flag=1;
if(t=='A') s1+=a;
else if(t=='B') s2+=a;
else s3+=a;
}
if(!flag)
{
tmp=s1+s2+s3;
if(s1>600 || s2>600 ||s3>600||tmp>1000)
continue;
v[r++]=tmp*100;
}
else flag=0;
}
memset(dp,0,sizeof(dp));
for(int i=0;i<r;i++)
{
for(int j=sum*100;j>=v[i];j--)
dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
}
int ans=sum*100;
printf("%.2lf\n",dp[ans]*1.0/100);
}
return 0;
}
hdu 1171 Big Event in HDU (多重背包)
直接按《背包九讲》的模板写就可以了。
吐糟:我为什么每次都要把二进制优化 的位运算移位方向弄反= =诶。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 0xffffff
using namespace std;
int v[55],c[55];
int p[5000],dp[500010];
int main()
{
int n,sum,tmp,r,u;
while(scanf("%d",&n)!=EOF)
{
if(n<0) break;
sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&v[i],&c[i]);
sum+=v[i]*c[i];
}
u=sum/2;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
if(v[i]*c[i]>u)
{
for(int j=v[i];j<=u;j++)
{
dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
}
}
else
{
tmp=1;r=0;
while(tmp<c[i])
{
p[r++]=tmp*v[i];
c[i]-=tmp;
tmp<<=1;
}
if(c[i])
p[r++]=c[i]*v[i];
for(int k=0;k<r;k++)
{
for(int j=u;j>=p[k];j--)
{
dp[j]=max(dp[j],dp[j-p[k]]+p[k]);
}
}
}
}
printf("%d %d\n",sum-dp[u],dp[u]);
}
return 0;
}
hdu 2602 Bone Collector (01背包)
没什么好说的。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int v[1010],w[1010];
int dp[1010];
int main()
{
int T,n,vv;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&vv);
for(int i=0;i<n;i++)
scanf("%d",&w[i]);
for(int i=0;i<n;i++)
scanf("%d",&v[i]);
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
for(int j=vv;j>=v[i];j--)
{
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
printf("%d\n",dp[vv]);
}
return 0;
}