您的位置:首页 > Web前端

背包系列练习及总结(hud 2602 && hdu 2844 Coins && hdu 2159 && poj 1170 Shopping Offers && hdu 3092 Least common multiple && poj 1015 Jury Compromise)

2017-05-06 15:55 477 查看
作为一个oier,以及大学acm党背包是必不可少的一部分。好久没做背包类动规了。久违地练习下-。-

dd__engi的背包九讲:http://love-oriented.com/pack/

鸣谢http://blog.csdn.net/eagle_or_snail/article/details/50987044,这里有大部分比较有趣的dp练手题。

hud 2602 01背包板子题

1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4 #define clr(x) memset(x,0,sizeof(x))
5 #define clrmin(x) memset(x,-0x3f3f3f3f,sizeof(x))
6 using namespace std;
7 int dp[210][50][810];
8 int c[210],v[210],ans[50];
9 int n,m,k,s,t,l,r;
10 int max(int a,int b)
11 {
12     return a>b?a:b;
13 }
14 int main()
15 {
16     int kase=0,fit;
17     while(scanf("%d%d",&n,&m)!=EOF && n>0 && m>0)
18     {
19         clrmin(dp);
20         dp[0][0][400]=0;
21         for(int i=1;i<=n;i++)
22         {
23             scanf("%d%d",&l,&r);
24             c[i]=l-r;
25             v[i]=l+r;
26             dp[i][0][400]=0;
27         }
28         for(int i=1;i<=n;i++)
29         {
30             for(int j=m;j>0;j--)
31             {
32                 for(int k=(400<400+c[i])?400:400+c[i];k>=c[i]-400 && k>=-400;k--)
33                 {
34                     dp[i][j][k+400]=max(dp[i-1][j][k+400],dp[i-1][j-1][k-c[i]+400]+v[i]);
35                 }
36             }
37 /*                for(int ii=0;ii<=2;ii++)
38                 {
39                     for(int jj=398;jj<=406;jj++)
40                         printf("%d ",dp[i][ii][jj]>=0?dp[i][ii][jj]:-1);
41                     printf("\n");
42                 } */
43         //    printf("%d\n",dp[i][0][400]);
44         }
45         for(int i=0;i<=400;i++)
46         {
47             if(dp
[m][400+i]>0 || dp
[m][400-i]>0)
48             {
49                 if(dp
[m][400+i]>dp
[m][400-i])
50                     l=i;
51                 else
52                     l=-i;
53                 break;
54             }
55         }
56         printf("Jury #%d\n",++kase);
57         printf("Best jury has value %d for prosecution and value %d for defence:\n",(l+dp
[m][400+l])/2,(dp
[m][400+l]-l)/2);
58         l=400+l;
59         t=m;
60         for(int i=n;i>=1;i--)
61             if(dp[i][m][l]==dp[i-1][m-1][l-c[i]]+v[i])
62             {
63                 ans[m]=i;
64                 m--;
65                 l-=c[i];
66                 if(m==0)
67                     break;
68             }
69         for(int i=1;i<=t;i++)
70             printf(" %d",ans[i]);
71         printf("\n\n");
72     }
73     return 0;
74 }


二维01背包

做了这么些题,可以发觉背包题需要对费用很敏感,对于是精确到某个容量下的(即装满)的背包和非精确(即最多为该容量)的背包,赋初值的方式是不同的。还有要善于发掘背包的费用,费用可以是任何可以用来递推的下标。可能是多维(2以上)要擅用状态压缩使得问题简单化。

当然对于dp都有一个共同点:数据范围特别小。注意下数据范围有可能就能发现他是一道dp甚至背包,从而快速解决。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: