ZOJ 2059 The Twin Towers
2016-03-09 21:45
323 查看
双塔DP。
dp[i][j]表示前i个物品,分成两堆(可以不全用),价值之差为j的时候,较小一堆的价值为dp[i][j]。
dp[i][j]表示前i个物品,分成两堆(可以不全用),价值之差为j的时候,较小一堆的价值为dp[i][j]。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int dp[105][4000 + 10]; int a[105]; int n, sum; void read() { for (int i = 1; i <= n; i++) scanf("%d", &a[i]); } void work() { sum = 0; for (int i = 1; i <= n; i++) sum = sum + a[i]; memset(dp, -1, sizeof dp); int h; h = a[1]; dp[1][h + sum] = dp[1][0 - h + sum] = dp[1][sum] = 0; for (int i = 2; i <= n; i++) { h = a[i]; for (int j = 0; j <= sum*2; j++) dp[i][j] = dp[i - 1][j]; for (int j = 0; j <= sum*2; j++) { if (dp[i - 1][j] == -1) continue; int tmp = j - sum; if (tmp >= 0) { dp[i][h + tmp + sum] = max(dp[i][h + tmp + sum], dp[i - 1][j]); dp[i][tmp - h + sum] = max(dp[i][tmp - h + sum], dp[i - 1][j] + min(tmp, h)); } else if (tmp<0) { tmp = -tmp; dp[i][0 - (tmp + h) + sum] = max(dp[i][0 - (tmp + h) + sum], dp[i - 1][j]); dp[i][h - tmp + sum] = max(dp[i][h - tmp + sum], dp[i - 1][j] + min(tmp, h)); } } } int ans = 0; for (int i = 1; i <= n; i++) ans = max(ans, dp[i][sum]); if (ans == 0) printf("Sorry\n"); else printf("%d\n", ans); } int main() { while (~scanf("%d", &n)) { read(); if (n < 0) break; if (n <=1) printf("Sorry\n"); else work(); } return 0; }
相关文章推荐
- 基础的图书馆管理系统
- while循环计算1到100之和
- 使用common-fileUpload和 Spring中MultipartHttpServletRequest实现文件上传
- Android中的缩略图制作
- 异常控制try-throw-catch用法小结
- OC-类和对象
- 第二周项目1宣告主权
- Activity生命周期
- Linux下查看/修改系统时区、时间
- 中缀表达式转化成后缀表达式
- unity视频笔记——flappy bird
- while循环计算1到100之和
- WIN32汇编语言在窗口添加按钮,点击按钮实现跳转到一个程序或者一个URL。。。
- hibernate和mybatis比较
- 第二周项目3——小试循环(1)
- Oracle数据库的权限、用户、角色管理
- POJ - 2115 C Looooops(扩展欧几里德求解模线性方程(线性同余方程))
- Conditional Random Fields as Recurrent Neural Networks
- poj 2676 深搜之sudo
- 关于VLOOUP函数与index match函数