pku1882 Stamps(http://poj.org/problem?id=1882)(博客搬迁)
来源:互联网 发布:mac air键盘灯不亮 编辑:程序博客网 时间:2024/05/17 03:26
分析1 :百度和goole了,都说是完全背包,可是我怎么想都不像,只是循环的形式相似,其本质我认为不是完全背包问题。我以为这更像是枚举。
code:
#include<stdio.h>
#include<string.h>
int main()
{
int s, t;
int n;
int i, j, k;
int a[11], sum[10003];
int max, b[11];
while(scanf("%d", &s) && s)
{
max = 0;
scanf("%d", &t);
while(t--)
{
int i, j;
int p;
scanf("%d", &n);
for(j = 1; j <= n; j++)
scanf("%d", &a[j]);
memset(sum, 0, sizeof(sum));
int tmp;
tmp = 0;
sum[0] = 1;
for(i = 1; i <= s; i++)
{
for(j = tmp; j >= 0; j--)
{
if(sum[j])
{
for(int k = 1; k <= n; k++)
{
sum[j+a[k]] = 1;
}
}
}
tmp += a[n];
}
i = 1;
while(sum[i])i++;
if(max < i)
{
max = i;
for(j = 1; j <= n; j++)
b[j] = a[j];
b[0] = n;
}
else if(max == i && b[0] > n)
{
max = i;
for(j = 1; j <= n; j++)
b[j] = a[j];
b[0] = n;
}
else if(max == i && b[0] == n && b[b[0]] > a[n])
{
max = i;
for(j = 1; j <= n; j++)
b[j] = a[j];
b[0] = n;
}
}
printf("max coverage = %d :", max-1);
for(i = 1; i <= b[0]; i++)
printf(" %d",b[i]);
printf("\n");
}
}
今天又重新做了pku1882,确实用完全背包的思想可以做出来,但是比上面的枚举的方法更慢,其中的缘由也很好理解。这也给我一个启示——掌握思想后,要灵活转变。
在这题中,解题的一个要点是用尽可能少的张数凑成最大的值,由此可以写出状态方程:
sum[k] = sum[k] > sum[k-j*a[i]]+j ? sum[k-j*a[i]]+j : sum[k]。
把可能的最大值当做v,sum[i]中存的是邮票的张数。
code:
#include<stdio.h>
#include<string.h>
{
int s, t;
int n;
int i, j, k;
int a[11], sum[10003];
int max, b[11];
while(scanf("%d", &s) && s)
{
max = 0;
scanf("%d", &t);
while(t--)
{
int i, j;
int p;
scanf("%d", &n);
for(j = 1; j <= n; j++)
scanf("%d", &a[j]);
memset(sum, -1, sizeof(sum));
int tmp;
tmp = s*a[n];
sum[0] = 0;
for(i = 1; i <= n; i++) //完全背包思想
{
for(j = 1; j <= s; j++)
{
for(k = j*a[i]; k <= tmp; k++)
{
if(sum[k-j*a[i]] != -1)
{
if(sum[k] == -1 || sum[k-j*a[i]]+j <= sum[k])
if(sum[k-j*a[i]]+j <=s)sum[k] = sum[k-j*a[i]]+j;
}
}
}
} //end pack
i = 1;
while(sum[i] != -1)i++;
if(max < i)
{
max = i;
for(j = 1; j <= n; j++)
b[j] = a[j];
b[0] = n;
}
else if(max == i && b[0] > n)
{
max = i;
for(j = 1; j <= n; j++)
b[j] = a[j];
b[0] = n;
}
else if(max == i && b[0] == n && b[b[0]] > a[n])
{
max = i;
for(j = 1; j <= n; j++)
b[j] = a[j];
b[0] = n;
}
}
printf("max coverage = %d :", max-1);
for(i = 1; i <= b[0]; i++)
printf(" %d",b[i]);
printf("\n");
}
}
- pku1882 Stamps(http://poj.org/problem?id=1882)(博客搬迁)
- (博客搬迁)pku2231 Moo Volume(数学题http://poj.org/problem?id=2231)
- (博客搬迁啦)pku1276多重背包问题(http://poj.org/problem?id=1276)
- POJ 1251(http://poj.org/problem?id=1251)
- http://poj.org/problem?id=2965
- http://poj.org/problem?id=2075
- http://poj.org/problem?id=1125
- http://poj.org/problem?id=2983
- http://poj.org/problem?id=2406
- http://poj.org/problem?id=1961
- http://poj.org/problem?id=1486
- http://poj.org/problem?id=1062
- http://poj.org/problem?id=2983
- http://poj.org/problem?id=3159
- http://poj.org/problem?id=1201
- http://poj.org/problem?id=3259
- http://poj.org/problem?id=3233
- http://poj.org/problem?id=1273
- Apache、Tomcat、JBoss、WebLogic的区别与关系
- aodv-uu-0.9.6中的readme.ns
- XML编程(CRUD)
- 关于网上银行支付方式,参考后修改的
- ckeditor中关于模板的自定义
- pku1882 Stamps(http://poj.org/problem?id=1882)(博客搬迁)
- Queue和Stack
- 总结java socket编程
- mvc
- DTD规范XML文档
- 数据库连接池、反射和工厂模型
- Duplicate spring bean id问题排查
- 购物车的实现步骤
- 服务器配置(apache)