背包问题

来源:互联网 发布:网络教育的意义 编辑:程序博客网 时间:2024/05/17 08:06

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];   //数组一定要开这么大,否则REint 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 0xffffffusing 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;}




0 0
原创粉丝点击