HDU 2829 斜率优化DP Lawrence
2015-07-31 21:54
465 查看
题意:n个数之间放m个障碍,分隔成m+1段。对于每段两两数相乘再求和,然后把这m+1个值加起来,让这个值最小。
设:
d(i, j)表示前i个数之间放j个炸弹能得到的最小值
sum(i)为前缀和,cost(i)为前i个数两两相乘之和。
则有状态转移方程:
代码君
设:
d(i, j)表示前i个数之间放j个炸弹能得到的最小值
sum(i)为前缀和,cost(i)为前i个数两两相乘之和。
则有状态转移方程:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000 + 10; const int INF = 0x3f3f3f3f; int n, m; int a[maxn], sum[maxn], cost[maxn]; int d[maxn][maxn], s[maxn][maxn]; int inline w(int k, int j) { return cost[j] - cost[k-1] - sum[k-1] * (sum[j] - sum[k-1]); } int main() { while(scanf("%d%d", &n, &m) == 2 && n) { m++; for(int i = 1; i <= n; i++) scanf("%d", a + i); for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + a[i]; for(int i = 2; i <= n; i++) cost[i] = cost[i-1] + sum[i-1] * a[i]; memset(d, 0, sizeof(d)); for(int i = 1; i <= m; i++) for(int j = i + 1; j <= n; j++) d[i][j] = INF; for(int i = 1; i <= n; i++) { d[1][i] = cost[i]; s[1][i] = 0; } for(int i = 2; i <= m; i++) { s[i][n+1] = n; for(int j = n; j >= i; j--) { for(int k = s[i-1][j]; k <= s[i][j+1]; k++) { int tmp = d[i-1][k] + w(k+1, j); if(tmp < d[i][j]) { d[i][j] = tmp; s[i][j] = k; } } } } printf("%d\n", d[m] ); } return 0; }
代码君
相关文章推荐
- if语句的运用
- hdu 5295 Unstable(计算几何)
- mac 下 swoole 环境搭建
- *HDU 2196 - Computer(树形DP)
- 学习hibernate遇到的问题1
- Objective-C类和对象
- Mysql Client
- poj 2184 - Cow Exhibition (01背包) 解题报告
- mysql ERROR 1049 (42000): Unknown database '******' ”错误处理办法
- xcode6 ios ios simulator Home键
- 微信JSSDK分享接口中wx.config 出现invalid signature问题的解决办法
- mongodb与mysql命令对比
- C++读dat文件
- [记录]学习<<QT学习之路2>>第四天
- ehcache memcache redis
- 【HTTP】URL与资源
- 有序单链表合并(递归法)
- C#接口性能测试--计算执行时间
- Android 通过Uri获取Bitmap对象
- 《差分约束系统》详解