hdu-1171-Big Event in HDU-一维背包转换为01背包或多重背包(或用母函数解决)

原创 2018年04月17日 19:28:33

Big Event in HDU

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 47907    Accepted Submission(s): 16464


Problem Description
Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don't know that Computer College had ever been split into Computer College and Software College in 2002.
The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0<N<1000) kinds of facilities (different value, different kinds).
 

Input
Input contains multiple test cases. Each test case starts with a number N (0 < N <= 50 -- the total number of different facilities). The next N lines contain an integer V (0<V<=50 --value of facility) and an integer M (0<M<=100 --corresponding number of the facilities) each. You can assume that all V are different.
A test case starting with a negative integer terminates input and this test case is not to be processed.
 

Output
For each case, print one line containing two integers A and B which denote the value of Computer College and Software College will get respectively. A and B should be as equal as possible. At the same time, you should guarantee that A is not less than B.
 

Sample Input
2
10 1
20 1
3
10 1 
20 2
30 1
-1
 

Sample Output
20 10
40 40
 

Author
lcy
 

Recommend

We have carefully selected several similar problems for you:  2159 2844 1087 1176 1114 

01背包解决

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int v[5005];
int dp[255555];

int main()
{
	int n,i,j,l,a,b,sum;
	while(~scanf("%d",&n)&&n>0)
	{
		memset(dp,0,sizeof(dp));
		memset(v,0,sizeof(v)); 
		l=0;
		sum=0;
		for(i=0;i<n;i++)
		{
			scanf("%d%d",&a,&b);
			while(b--){
				v[l++]=a;
				sum+=a;
			} 
		}
		for(i=0;i<l;i++)
			for(j=sum/2;j>=v[i];j--)
			dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
		
		printf("%d %d\n",sum-dp[sum/2],dp[sum/2]);
	}
    
	return 0;
} 

多重背包

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int v[55];
int dp[250015];
int num[55];
int main()
{
	int n,i,j,k,l,a,b,sum;
	while(~scanf("%d",&n)&&n>0)
	{
		memset(dp,0,sizeof(dp));
		sum=0;
		for(i=0;i<n;i++)
		{
			scanf("%d%d",&v[i],&num[i]);
				sum+=num[i]*v[i];
		}
		for(i=0;i<n;i++)
		  for(k=0;k<num[i];k++)
			for(j=sum/2;j>=v[i];j--)
			  dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
		
		printf("%d %d\n",sum-dp[sum/2],dp[sum/2]);
	} 
	return 0;
} 

母函数模板正在研究附上

母函数模板

#include<cstdio>
typedef long long LL;
const int N = 100 + 5;//假如题目只问到100为止 
const int MAX = 3;//题目只有1,2,3这3种邮票 
LL c1[N], c2[N];//c2是临时合并的多项式,c1是最终合并的多项式 
int n;
void init(){
    c1[0] = 1;//一开始0的情况算一种 
    for(int i = 1; i <= MAX; i ++){//把1分到MAXN的邮票合并,变成一个多项式 
        for(int j = 0; j < N; j += i){//i分的邮票,步长是i
            for(int k = 0; j + k < N; k ++){//从x^0到x^N遍历一遍 
                c2[j + k] += c1[k];//因为j的所有项系数为1,所以c1[k]可以看成c1[k]*1; 
            }
        } 
        for(int j = 0; j < N; j ++){//把c2的数据抄到c1,清空c2 
            c1[j] = c2[j];
            c2[j] = 0;
        }
    }
} 
int main(){
    init();
    while(scanf("%d", &n) != EOF){
        printf("%I64d\n", c1[n]);
    }
}

大佬代码

#include<stdio.h>
int c1[250001],c2[250001];    //这个地方开始把题目看错了,导致数组开小了
int a[55][2];
int main()
{
 int i,j,k,s,n;
 while(scanf("%d",&n)&&n>0)
 {
  s=0;     //开始忘了初始化,输入数据后,一直不能输出
  for(i=0;i<n;i++)
  {
   scanf("%d%d",&a[i][0],&a[i][1]);
   s+=a[i][0]*a[i][1];
  }
  for(i=0;i<=s;i++)
  {
   c1[i]=0;c2[i]=0;
  }
  for(i=0;i<=a[0][1];i++)
   c1[i*a[0][0]]=1;
  for(i=1;i<n;i++)
  {
   for(j=0;j<=s;j++)
    for(k=0;k<=a[i][0]*a[i][1];k+=a[i][0])
     c2[j+k]+=c1[j];
    for(j=0;j<=s;j++)
    {
     c1[j]=c2[j];
     c2[j]=0;
    }
  }
  if(s%2==0)i=s/2;
  else i=s/2+1;
  for(j=i;;j++)
   if(c1[j]!=0)break;
   printf("%d %d\n",j,s-j);
 }
 return 0;
}


彻底掌握 Javascript(二十三)函数的高级技法【专家辅导】

课程讲解了一些函数的技巧,包括函数的 curry 、即时函数、闭包等技法。
  • 2017年06月30日 21:17

01背包,完全背包,多重背包的个人总结

大一刚接触背包问题的时候就觉得绕。那时候真的是一点代码基础都没有强行去理解。每次都是以失败告终,一直到大二都还不会写背包问题。 后来某次模拟赛之后碰到了背包问题,觉得这个还是挺简单的,终于是下定决心准...
  • tinyguyyy
  • tinyguyyy
  • 2016-04-20 22:08:53
  • 7269

01背包 ,完全背包,多重背包 dp (动态规划入门dp)

dp 动态规划,确实难啃, 光 最简单的 背包问题,就 费老大劲. 思想! 思想! 思想!   类似于递推, 局部找 关系.  背包问题,  就两种状态  放还是不放?   其实关于背包放不放的问题,...
  • sizaif
  • sizaif
  • 2017-04-12 22:44:42
  • 1240

背包问题——01背包、完全背包、多重背包、混合三种背包问题

转自: http://apps.hi.baidu.com/share/detail/14968747 P01: 01背包问题 题目 有N件物品和一个容量为V的背包。第i...
  • hcwzq
  • hcwzq
  • 2011-08-04 21:26:43
  • 1796

01背包的理解,二维数组化一维数组的理解(附hdu2602 Bone Collector)

01背包问题:有n个物品和一个容量为v的背包,用val[i]表示第i个物品的价值,用vol[i]表示第i个物品的体积,那么,如何使背包里装的物品的总价值最大呢?贪心是不行的,举个反例:n=3, v=1...
  • qq_33279781
  • qq_33279781
  • 2016-07-30 16:41:00
  • 1133

史上最易懂的01背包,完全背包,多重背包讲解

背包之01背包、完全背包、多重背包详解   PS:大家觉得写得还过得去,就帮我把博客顶一下,谢谢。 首先说下动态规划,动态规划这东西就和递归一样,只能找局部关系,若想全部列出来,是很难的,比如汉诺塔。...
  • qq_34374664
  • qq_34374664
  • 2016-08-17 14:02:35
  • 3406

poj1276 多重背包问题 转换为经典的01背包

之前做的一个方法是进行多重背包的基本算法 但是超时了 后来看了转换成01背包的方法 不是很理解 但是模板拿来直接用了 就可以过 在进行转换为01背包之后直接用01背包的算法 转换方法如下 ...
  • Han_DV
  • Han_DV
  • 2015-08-06 09:32:05
  • 203

01背包模板、完全背包 and 多重背包(模板)

01背包模板、完全背包 and 多重背包(模板)
  • u012860063
  • u012860063
  • 2014-06-21 09:41:03
  • 3556

多重背包转换成完全背包和01背包

多重背包转换成完全背包和01背包 详情看 HDU 2844 Coins (动规)
  • qq2256420822
  • qq2256420822
  • 2014-07-21 21:46:20
  • 559

背包模板(01,完全,多重背包的二进制优化和单调队列优化

背包问题 1,01背包 背包问题的基础,总体积为V的背包,有n件体积v【i】,价值w【i】的物品,求能装物品的最大总价值 void zero(int v,int w) { for(int j=V;j...
  • jerans
  • jerans
  • 2017-02-08 00:15:18
  • 850
收藏助手
不良信息举报
您举报文章:hdu-1171-Big Event in HDU-一维背包转换为01背包或多重背包(或用母函数解决)
举报原因:
原因补充:

(最多只允许输入30个字)