UVA 562 Dividing coins 分硬币(01背包,简单变形)

题意:一袋硬币两人分,要么公平分,要么不公平,如果能公平分,输出0,否则输出分成两半的最小差距。

思路:将提供的整袋钱的总价取一半来进行01背包,如果能分出出来,就是最佳分法。否则背包容量为一半总价的包能装下的硬币总值就是其中一个人能分得的最多的钱了,总余下的钱减去这包硬币总值。(只需要稍微考虑一下总值是奇数/偶数的问题)

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <cmath>
 5 using namespace std;
 6 const int N=100000;
 7 int w[N], dp[N];
 8
 9 void cal(int n, int cnt)
10 {
11     int m;
12     if(cnt&1==1)    m = (cnt>>1) + 1;//奇数
13     else            m=cnt>>1;
14
15     for(int i=0; i<n; i++)
16         for(int j=m; j>=w[i]; j--)
17             dp[j]=max( dp[j-w[i]]+w[i], dp[j] );
18
19     if(cnt&1==1)//奇数
20     {
21         if(dp[m]==m)    cout<<"1"<<endl; //最公平
22         else    cout<<cnt-dp[m]-dp[m]<<endl;
23     }
24     else
25     {
26         if(dp[m]==m)    cout<<"0"<<endl;  //最公平
27         else            cout<<cnt-dp[m]-dp[m]<<endl;
28     }
29
30 }
31
32 int main()
33 {
34     //freopen("input.txt","r",stdin);
35     int t, n, cnt;
36     cin>>t;
37     while(t--)
38     {
39         memset(dp, 0, sizeof(dp));
40         memset(w, 0, sizeof(w));
41         cin>>n;
42         cnt=0;
43         for(int i=0; i<n; i++)
44         {
45             scanf("%d",&w[i]);
46             cnt+=w[i];
47         }
48         if(n==0)
49             cout<<"0"<<endl;
50         else if(n==1)
51             cout<<w[0]<<endl;
52         else if(n==2)
53             cout<<abs(w[0]-w[1])<<endl;
54         else
55             cal(n, cnt);
56     }
57     return 0;
58 }

AC代码

时间: 2024-08-05 07:09:15

UVA 562 Dividing coins 分硬币(01背包,简单变形)的相关文章

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

uva 562 Dividing coins

Dividing coins It's commonly known that the Dutch have invented copper-wire. Two Dutch men were fighting over a nickel, which was made of copper. They were both so eager to get it and the fighting was so fierce, they stretched the coin to great lengt

UVA 562 Dividing coins (01背包)

//平分硬币问题 //对sum/2进行01背包,sum-2*dp[sum/2] #include <iostream> #include <cstring> #include <algorithm> using namespace std; int value[100000],dp[100000]; int main() { int n,m,sum,sum1; cin>>n; while(n--) { cin>>m; sum=0; for(int

(背包dp)UVA - 562 Dividing coins

题意:有n个硬币,每个硬币有个价值,两个人分配硬币,要求最公平分配时候两人拿到的钱的差. 分析:很明显,两人拿到的钱的差越小越公平. 一开始想,一定是一人一半最公平,所以直接把总和sum/2,对着half跑01背包,但是WA了,修改后分别讨论奇偶,额外进行一次sum-half的01背包,也WA,仔细想想觉得有些漏洞. 所以,这题其实可以干脆直接跑sum的背包,不断更新ans=min(ans,sum-dp[j]*2)就行了.如果ans==inf,表示不能分,也就是1个,这时输出0. 代码: 1 #

UVA 562 Dividing coins (01背包基础)

[题目链接]:click here~~ 代码: /* * Problem: UVA No.562 * Running time: 0MS * Complier: C++ * Author: ACM_herongwei * Create Time: 11:12 2015/9/9 星期三 * zeroonebags * 将金币总价值的一半作为背包容量,然后zeronebags */ #include <stdio.h> #include <iostream> #include <

poj 2184 0---1背包的变形

这题是0--1背包的变形,对理解0--1背包有很大的帮组 题意:要选一些牛去参见展览,每个牛有幽默.智慧两个选择标准,要求选的这些牛使得幽默和智慧的总和最大且幽默和智慧的每个总和都必须是大于等于0: 刚看的这个题目是时候,知道是一个0--1背包的的题目,但就是不知道怎么来写出状态转移方程,因为题中的两个变量都是有负值的. 看了大牛的解题报告才知道. 我们可以把幽默个变量看成是体积 , 智慧看成是价值. 我们可以把每个牛幽默的值 , 放在一个坐标上,让后整体往右移,使得最小值为 0 , 那么这时候

hdu 1574 RP问题 01背包的变形

hdu 1574 RP问题 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1574 分析:01背包的变形. RP可能为负,所以这里分两种情况处理一下就好. 初始化要注意. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define inf 0x3f3f3f3f int

分辣条-01背包恰好装满情况

分辣条 发布时间: 2016年6月26日 20:36   最后更新: 2016年6月26日 20:37   时间限制: 1000ms   内存限制: 128M 描述 "你喝的酸奶是我买的,辣条也是我买的,你现在要跟我分手,你把我当什么?" "因为你每次分辣条的时候都比我多一根!" 可见分好辣条是一件多么重要的事情.. 现在有n(1<=n<=200)根辣条,每根辣条的重量为a1,a2...ai..an(1<=ai<=100). 那么能不能把这些

01背包的变形

http://poj.org/problem?id=3211 Description Dearboy was so busy recently that now he has piles of clothes to wash. Luckily, he has a beautiful and hard-working girlfriend to help him. The clothes are in varieties of colors but each piece of them can b