Day 3
动态规划的模版问题——
背包问题
说起背包,我们之前在xc那里学过一些
不过,我都怎么没认真听,~~哈哈对不起啊xc
因为那里人实在是太多啦,搞集训当然要弄点成绩出来
于是,在那写了几天的背包还不如在这里专心搞个一天
当然,一切都是我的错,我的错。。。
我真的不是说纪中不好,但是。。。呃,没有但是,是我没有专心听
是我。。
MORNING
上午讲了
01背包
完全背包
多重背包
混合背包
我是这么理解的:
- 01背包两个for,一个枚举物品编号,一个枚举背包剩余容量
- 完全背包再加一个for,枚举物品数量
- 多重背包将完全背包的第三个for改一下,限制物品数量
- 混合背包。。顾名思义,就是几个背包一起扛
AFTERNOON
下午就很残酷啦,面对扑面而来的4道,不知道是什么背包的题目,我胆战心惊的打开A题,然后花了很久的时间就为了A掉这题(Sorry,黄皓我下次再也不敢了)。然后紧接着又A了一题。对,你木有听错,我只A了两题
A题:http://acm.hdu.edu.cn/showproblem.php?pid=1059
B题:http://poj.org/problem?id=1276
C题:http://poj.org/problem?id=2392
D题:http://acm.hdu.edu.cn/showproblem.php?pid=1171
其实只要分析一下哪个值对应的是背包的哪一个值,
然后套模版就能做对的(其他大佬说的!!其实我也是这么想的)
老师也说今天的很简单
然后,为此贴上A、C代码
A
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int dp[100000];
int a[11],sum,v,i,j,k,cnt,cas=1;
int main()
{
while(~scanf("%d",&a[1]))
{
sum = a[1];
for(i = 2;i<=6;i++)
{
scanf("%d",&a[i]);
sum+=i*a[i];
}
if(!sum)
break;
printf("Collection #%d:\n",cas++);
if(sum%2)
{
printf("Can't be divided.\n\n");
continue;
}
v = sum/2;
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(i=1;i<=6;i++)
{
if(!a[i])
continue;
for(j=1;j<=a[i];j*=2)
{
cnt=j*i;
for(k=v;k>=cnt;k--)
{
if(dp[k-cnt])
dp[k] = 1;
}
a[i]-=j;
}
cnt = a[i]*i;
if(cnt)
{
for(k = v;k>=cnt;k--)
{
if(dp[k-cnt])
dp[k] = 1;
}
}
}
if(dp[v])
printf("Can be divided.\n\n");
else
printf("Can't be divided.\n\n");
}
return 0;
}
C
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define INF 1<<30
#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?a:b)
struct s
{
int h,num,mh;
}b[440];
int dp[40040];
int cmp(const void *a,const void *b)
{
return (*(struct s *)a).mh-(*(struct s *)b).mh;
}
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
int i,j,k;
for(i=0;i<n;i++)
{
scanf("%d%d%d",&b[i].h,&b[i].mh,&b[i].num);
}
qsort(b,n,sizeof(b[0]),cmp);
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
{
for(k=1;k<=b[i].num;k++)
{
for(j=b[i].mh;j>=b[i].h;j--)
{
dp[j]=max(dp[j],dp[j-b[i].h]+b[i].h);
}
}
}
int ans=0;
for(i=0;i<=b[n-1].mh;i++)
{
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
}
}
然后晚上全都改完啦