荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: hsfzer (NoName), 信区: ACMICPC
标 题: 解题随笔:UVA 562 Dividing Coins (陈伟坚)
发信站: 荔园晨风BBS站 (Sun Oct 18 17:19:07 2009), 站内
解题随笔:UVA 562 Dividing Coins (陈伟坚)
题目大意:将一堆不同面值的硬币,尽量平均地分给两个人,也就是,找到一种分法,使得
两堆硬币的面值之和最小。
思路:刚开始,拿到题目的时候,有点茫然。细想了一下,原来是一道简单的01背包的题目
。首先,将所有硬币的面值加起来,得到一个值SUM。然后,以SUM的一半,也就是(SUM/2
)作为背包的总容量。计算在(SUM/2)的总容量下,能取到得硬币的总面值,设为TMP。那么
最后结果ANS=SUM-TMP-TMP。
描述性证明如下:设分成的两堆硬币总面值分别为A,B.不妨设A<=B.由于A+B=SUM。那么有
A<=(SUM/2).为了使ANS(=B-A)的值最小,那么A应该尽量地大(因为A+B=SUM是定值)。在
A<=(SUM/2)的情况下,使A尽量大,这是一个典型的01背包问题。
#include <stdio.h>
#include <memory.h>
int n,coin[100];
int dp[100][30000];
int dfs(int pos,int w);
int main()
{
int t,i;
int sum,tmp,ans;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
sum=0;
for (i=0;i<n;i++)
{
scanf("%d",&coin[i]);
sum+=coin[i];
}
memset(dp,-1,sizeof(dp));
tmp=dfs(0,sum/2);
ans=sum-tmp-tmp;
printf("%d\n",ans);
}
return 0;
}
int dfs(int pos,int w)
{
int tmp;
if (pos==n)return 0;
if (dp[pos][w]!=-1)return dp[pos][w];
tmp=dfs(pos+1,w);
if (w-coin[pos]>=0&&tmp<dfs(pos+1,w-coin[pos])+coin[pos])
tmp=dfs(pos+1,w-coin[pos])+coin[pos];
dp[pos][w]=tmp;
return dp[pos][w];
}
--
※ 来源:·荔园晨风BBS站 http://bbs.szu.edu.cn·[FROM: 192.168.14.29]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店