ACM: 动态规划题+剪枝 toj 3904
2016-05-19 23:21
323 查看
Points cakes
描述
A mother has n different
sizes of cake,she wants to give to his two
children by a fair way(which may not completely average, but
requires minimum),
you can help she solve this problem?
输入
there are many case of
testdata,for each testdata,
first line: an integer
n(3<=n<=1000), means how many cakes
does the mother has.
second line: n integers, for each
a[i](1<=a[i]<=50), a[i] means the
size of ith cake.
输出
for each teatdata, output
two integers x, y(x<=y)
x, y means how many cakes do the two children have.
样例输入
3
1 2 3
样例输出
3
3
题意: 分配蛋糕, 有n块不同大小的蛋糕, 要求分配给两个人, 如果不可以实现分配均匀(重量相同分配).
尽量达到大小相近.
解题思路:
1. 动态规划: 决策1: 使用当前块, w+a[i] <= sum_half;
==> DP(w+a[i],i+1);
决策2:
不使用当前块, 直接跳过. DP(w,i+1);
2. 纠结一天问题: (1).递归出口是 i == n+1; (一开始忽略了最后一块i==n是错误的)
(2).剪枝:
if(i == n+1 || maxt == sum_half) 递归出口增加.
已经满足条件的不需要再将递归树伸展了. (TLE解决)
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
#define MAX 1005
int n;
int a[MAX];
int maxt, sum;
int sum_half;
void DP(int w,int reLen)
{
if(reLen == n+1 || maxt == sum_half)
{
if(maxt < w
&& w <= sum_half)
maxt = w;
return ;
}
if(w+a[reLen] <= sum_half)
DP(w+a[reLen],reLen+1);
DP(w,reLen+1);
}
int main()
{
int i, j;
// freopen("input.txt","r",stdin);
while(scanf("%d",&n) !=
EOF)
{
sum = 0;
for(i = 1; i <=
n; ++i)
{
scanf("%d",&a[i]);
sum +=
a[i];
}
maxt = 0;
sum_half = (sum%2==0 ? sum/2 :
sum/2+1);
DP(0,1);
int big = (maxt
> sum-maxt ? maxt : sum-maxt);
printf("%d
%d\n",sum-big,big);
}
return 0;
}
相关文章推荐
- ACM: 博弈题 poj 1067
- ACM: 贪心法 poj 1700
- ACM: 树状DP 动态规划题 poj 1463 …
- 第一章 答疑摘选
- ACM: 简单动态规划题 poj 2955
- Smooth Rotation of Object in UNITY
- spark-graphx新的里程碑GraphDataFrames
- ACM: 最大流问题 图论题 poj 2263
- ACM: 图论题+记忆DP poj 2662 (边…
- ACM: 二分图最大匹配 图论题 poj 2…
- ACM: 有向欧拉图 图论题 poj 1386 …
- ACM: 二分图最佳匹配 图论题 poj 3…
- ACM: 动态规划 poj 1014
- ACM: 搜索题 poj 1691 一觉醒来居…
- ACM: 动态规划 黑书上的题目
- ACM: 动态规划 华东师范OJ 1244 …
- ACM: 动态规划 poj 2192
- ACM: 变形的最大公共自序列 动态规…
- ACM: 暴力题 poj 1338
- ACM: 动态规划 poj1695