【POJ1882】Stamps,灵活多重背包,详细题意!!!(题解也有)

我之所以发题解(题意),就是因为百度搜索上发的太少了,而且还不清晰,所以:

题意:我直接拿数据说话吧(可以直接看下面的大号粗体字,如果你语文够好的话。)

5
2
4 1 4 12 21
4 1 5 12 28
10
2
5 1 7 16 31 88
5 1 15 52 67 99
6
2
3 1 5 8
4 1 5 7 8
0

第一行 5 是最多能拿5张邮票,第二行2是有两组邮票。

第三行4是该组有4张邮票,然后4个数是4个面额。

第五行“10”开始就是下一组数据了,输入到“0”为止。

现在数据说完了,拿第一组数据说题意。

两组邮票中每组都可以任意取不多于5张邮票,组成一个新的面额,显然可以取到1~71种新面额,而之后可能也能取到,但是就不连续了,就不算了。

现在问第几组能取到最大的连续面额。面额是多少,并输出该组邮票基础面额!

如果两组邮票最大连续面额相同,输出基础面额个数少的那个!

如果两组邮票基础面额个数相同,输出基础面额最大值最小的那个!

如果两组邮票基础面额最大值相同,输出前一组!

(输入面额时保证面额从小到大。)

题解:

每一组做一遍背包(DP)看最大连续和,然后输出符合要求的那个!

背包过程:多重背包。首先讲一下三种多重背包做法及时间复杂度(拆分物品转成01)是O(体积*物品总数(∑每个物品类型有多少个)),姑且认为每种物品个数相同,则时间复杂度是O(m*n*p),然后二进制拆分就变成了O(m*n*log(p)),然后用计数器优化就变成了O(m*n),

计数器优化:http://blog.csdn.net/vmurder/article/details/39473505

二进制优化:http://blog.csdn.net/vmurder/article/details/39472419

然后这道题是共用数量,所以计数器共用一下就好了(不过需要更新)

水水的代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 11
#define L 101
using namespace std;
struct Fiona
{
	int w[N],num,length;
	bool operator < (const Fiona &a)const
	{
		if(length!=a.length)return length>a.length;
		if(num!=a.num)return num<a.num;
		return w[num]<a.w[num];
	}
}s[N];

int n,m;
int cnt[N*L];
bool f[N*L];
int main()
{
//	freopen("test.in","r",stdin);
	int i,j,k,u,temp;
	while(scanf("%d",&m),m)
	{
		scanf("%d",&n);
		for(i=1;i<=n;i++)
		{
			scanf("%d",&s[i].num);
			for(j=1;j<=s[i].num;j++)scanf("%d",&s[i].w[j]);
			/*输入数据保证了升序*/
		}
		for(i=1;i<=n;i++)
		{
			memset(f,0,sizeof(f));
			f[0]=1;
			for(j=1;j<=s[i].num;j++)/*枚举物品*/
			{
				//memset(cnt,0,sizeof(cnt));
				temp=s[i].w[j]*m;
				for(k=s[i].w[j];k<=temp;k++)if(f[u=k-s[i].w[j]]&&cnt[u]<m)
				{
					if(!f[k]||cnt[k]>cnt[u]+1)
					{
						f[k]=1;
						cnt[k]=cnt[u]+1;
					}
				}
			}
			for(s[i].length=0;f[s[i].length+1];s[i].length++);
		}
		sort(s+1,s+n+1);
		printf("max coverage = %d :",s[1].length);
		for(i=1;i<=s[1].num;i++)printf(" %d",s[1].w[i]);
		puts("");
	}
	return 0;
}

复制去Google翻译翻译结果

时间: 2024-11-08 06:55:27

【POJ1882】Stamps,灵活多重背包,详细题意!!!(题解也有)的相关文章

【CJWYH】RHL的背包题解(多重背包)

题面 [问题描述] CJ中学组织学生出去春游,作为学神的RHL自然不会放过这一大好时机,他有n种物品,第i件物品有c[i]个,每个体积为v[i],价值为w[i],RHL现在有一个体积为V的背包,他想让他带的东西价值之和最大,且体积之和不超过V,你能帮帮他吗?注意物体不能分割. [输入] 输入文件名为bag.in,分为若干行.第一行包含两个正整数n,V. 第二行到第n+1行分别描述第i种物品的数量c[i],体积v[i],价值w[i] [输出] 输出文件名为bag.out,一行输出一个整数,表示最大

HDU 2191 多重背包

悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22865    Accepted Submission(s): 9661 Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市

HDU 2844 二进制优化的多重背包

Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11596    Accepted Submission(s): 4634 Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One

HDU 2082 找单词 (多重背包)

题意:假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到多少价值<=50的单词呢?单词的价值就是组成一个单词的所有字母的价值之和,比如,单词ACM的价值是1+3+14=18,单词HDU的价值是8+4+21=33.(组成的单词与排列顺序无关,比如ACM与CMA认为是同一个单词). 题解:把26个字母看做26种背包,有个数有价值,求价值不超过50的所有可能个数,就是标准的多重背包.

poj1014 Dividing (多重背包)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:id=1014">http://poj.org/problem?id=1014 Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbles. Th

hdu1059 dp(多重背包二进制优化)

hdu1059 题意,现在有价值为1.2.3.4.5.6的石头若干块,块数已知,问能否将这些石头分成两堆,且两堆价值相等. 很显然,愚蠢的我一开始并想不到什么多重背包二进制优化```因为我连听都没有听过```不得不吐槽自己的知识面太窄```于是,我用了母函数写这题,母函数的做法并没有问题,但是由于这道题的数据很大,母函数轻轻松松就超时了,于是,我又很努力地在母函数循环的优化上面想出路,改改改,各种改之后依旧TLE,01背包的做法显然也是会超时的,DISCUSS里的母函数做法优化方式都是模上一个大

背包问题入门(单调队列优化多重背包

背包问题 写这篇文章主要是为了帮帮新人吧,dalao勿喷.qwq 一般的背包问题问法 每种物品都有一个价值w和体积c.//这个就是下面的变量名,请看清再往下看. 你现在有一个背包容积为V,你想用一些物品装背包使得物品总价值最大. 01背包 多种物品,每种物品只有一个.求能获得的最大总价值. 我们考虑是否选择第i件物品时,是需要考虑前i-1件物品对答案的贡献的. 分析 如果我们不选择第i件物品,那我们就相当于是用i-1件物品,填充了体积为v的背包所得到的最优解. 而我们选择第i件物品的时候,我们要

POJ 3260 完全背包+多重背包+思维

传送门:https://vjudge.net/problem/20465/origin 题意:你有n种钞票,面值为c[i],数量为v[i],便利店老板有无数张面值为c[i]的钞票,问你买一个价值为T的物品,最少需要经手多少张钞票,老板找零的钞票数也算经手的钞票数 题解:因为我的钞票是有限的,所以将自己看作一个多重背包,老板的钞票是无限的,所以将老板的钞票看做一个完全背包,定义状态dp[i]最少花费多少张钞票可以买价值为i的物品 边界:dp[0]=0; 目的:ans=min(dp1[i]+dp2[

[hdu5445 Food Problem]多重背包

题意:一堆食物,有价值.空间.数量三种属性,一些卡车,有空间,价格,数量三种属性.求最少的钱(不超过50000)买卡车装下价值大于等于给定价值的食物,食物可以拆开来放. 思路:这题的关键是给定的条件:食物可以拆开来放.这个条件使得卡车和食物可以分开考虑,然后通过空间这个属性联系在一起.做两遍多重背包即可. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35