区间型动态规划 之 CODE[VS] 矩阵取数游戏 (2007年NOIP全国联赛提高组)
2015-11-03 15:08
507 查看
/* 分析: 对于n行输入,各行之间是独立的,只需要找到各行的最大值,它们的和即为答案。 由于:1<=n, m<=80,0<=aij<=1000,所以最大会出现 1000*(2^80) => 高精度计算 dp[i][j] := 每行取第i到j个数可得到的最大值。 对于输入的任一行a[m],第x次取数的状态转移为: dp[i][j] = 2*max(dp[i+1][j]+arr[i],dp[i][j-1]+arr[j]) (正常取数是由外向内,但步长是由小到大,相当于取数是由内向外,所以2要乘在外面,这样倍数会自然乘上) */
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstddef> #include <iterator> #include <algorithm> #include <locale> #include <cmath> #include <vector> #include <cstring> using namespace std; const int INF = 0x3f3f3f3f; const int MaxN = 85; const int MaxLen = 30; int n, m; struct node { int arr[MaxLen]; int len; node () { memset(arr, 0, sizeof(arr)); len = 0; } }; int arr[MaxN]; // a*2 node Mul(node a) { int carry = 0; for (int i = 0; i < a.len; ++i) { a.arr[i] = (a.arr[i] << 1) + carry; carry = a.arr[i] / 10; a.arr[i] %= 10; } if (carry != 0) { a.arr[a.len] = carry; ++(a.len); } return a; } node Add(node a, int val) { int carry = 0; for (int i = 0; i < a.len; ++i) { a.arr[i] += (val % 10 + carry); val /= 10; carry = a.arr[i] / 10; a.arr[i] %= 10; } while (val) { a.arr[a.len] += (val % 10 + carry); val /= 10; carry = a.arr[a.len] / 10; a.arr[a.len] %= 10; ++(a.len); } if (carry) { a.arr[a.len] = carry; ++(a.len); } return a; } node Add(node a, node b) { node tmp; int carry = 0; int len = max(a.len, b.len); for (int i = 0; i < len; ++i) { tmp.arr[i] = a.arr[i] + b.arr[i] + carry; carry = tmp.arr[i] / 10; tmp.arr[i] = tmp.arr[i] % 10; ++(tmp.len); } if (carry != 0) { tmp.arr[tmp.len] = carry; ++(tmp.len); } return tmp; } node Cmp(node a, node b) { if (a.len < b.len) { return b; } if (a.len > b.len) { return a; } for (int i = a.len - 1; i >= 0; --i) { if (a.arr[i] == b.arr[i]) continue; if (a.arr[i] > b.arr[i]) { return a; } else { return b; } } return a; } int main() { node ans; cin >> n >> m; for (int tn = 0; tn < n; ++tn) { node dp[MaxN][MaxN]; for (int tm = 0; tm < m; ++tm) { cin >> arr[tm]; // 初始化:dp[i][i] = (arr[i]<<1) int tmp = (arr[tm] << 1); // 不用while循环,防止 tmp=0 do { dp[tm][tm].arr[dp[tm][tm].len] = tmp % 10; ++(dp[tm][tm].len); tmp /= 10; } while (tmp); } for (int k = 1; k < m; ++k) { for (int i = 0; (i + k) < m; ++i) { /*node tmp1 = Add(dp[i + 1][i + k], arr[i]); node tmp2 = Mul(Add(dp[i + 1][i + k], arr[i]));*/ dp[i][i + k] = Mul(Cmp(Add(dp[i + 1][i + k], arr[i]), Add(dp[i][i + k - 1], arr[i+k]))); } } ans = Add(ans, dp[0][m - 1]); } for (int i = ans.len - 1; i >= 0; --i) { cout << ans.arr[i]; } cout << endl; #ifdef HOME cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl; #endif return 0; }
相关文章推荐
- Redis 常用命令
- oracle查询仅中文使用lengthb()方法
- Longest Increasing Subsequence
- Android开发之带图片的按钮
- effective c++ 若所有参数皆需要类型转换,请为此采用non-member函数
- ubuntu创建分区步骤
- Maven介绍
- opencv得到图像的RGB颜色直方图
- CUDA 技巧与经验 关于block、thread
- Android中的Selector的用法
- Single Number III
- Windows下编译objective-C
- nginx如何利用ngx_channel_t在进程间传递消息
- MyBatis学习总结(七)——Mybatis缓存
- 游戏摇杆之Easy Touch 3教程
- python随机读取文件中的某一行内容
- java WEB项目打包部署到tomcat
- Web API应用架构设计分析(2)
- 深入浅出看流媒体前世今生,分分钟二逼变牛逼
- 用apache-cxf生成webservice客户端的时候报错Parameter: shead already exists for method