UVA - 12594 Naming Babies(斜率优化)
来源:互联网 发布:勤思考研网络课程 编辑:程序博客网 时间:2024/06/14 06:51
题目大意:给出一个字符串,要求你将这个字符串分成k段
每段的代价为sigma(i - pos) * pos
求所有段的最小代价和
解题思路:用dp[i][j]表示前i个字符分成j段的最小代价和
得到转移方程dp[i][j] = dp[k][j - 1] + (0 * pos[k + 1] + 1 * pos[k + 2] + … + (i - k - 1) * pos[i]) - (pos[k + 1] ^ 2 + pos[k + 2] ^ 2 + … + pos[i] ^ 2)
=dp[k][j - 1] + (k * pos[k + 1] + (k + 1) * pos[k + 2] + … + (i - 1) * pos[i] ) -k * (pos[k + 1] + pos[k + 2] + … + pos[i]) - (pos[k + 1] ^ 2 + pos[k + 2] ^ 2 + … + pos[i] ^ 2)
很长的一个式子,接下来的问题就是处理括号里的那些数据了
用s1表示 (pos[k + 1] + pos[k + 2] + … + pos[i])的前缀和
用s2表示 (k * pos[k + 1] + (k + 1) * pos[k + 2] + … + (i - 1) * pos[i] )的前缀和
用s3表示(pos[k + 1] ^ 2 + pos[k + 2] ^ 2 +… + pos[i] ^ 2)的前缀和
则dp方程表示如下
dp[i][j] = dp[k][j - 1] + (s2[i] - s2[k]) - k * (s1[i] - s1[k]) - (s3[i] - s3[k])
设l > k,且点l比点k优
则dp[k][j - 1] + (s2[i] - s2[k]) - k * (s1[i] - s1[k]) - (s3[i] - s3[k]) >= dp[l][j - 1] + (s2[i] - s2[l]) - l * (s1[i] - s1[l]) - (s3[i] - s3[l])
化简得s1[i] >= ( (dp[l][j - 1] - s2[l] + s3[l] + l * s2[l]) - (dp[k][j - 1] - s2[k] + s3[k] + k * s2[k]) ) / (l - k)
因为s1随着i的递增而递增,所以得到斜率方程
#include <cstdio>#include <cstring>const int N = 20010;const int M = 30;typedef long long LL;char str[M], name[N];int n, m;int que[N], pos[M];LL s1[N], s2[N], s3[N], val[N], dp[510][N];void init() { scanf("%s%d", str, &m); int len = strlen(str); for (int i = 0; i < len; i++) pos[str[i] - 'a'] = i; scanf("%s", name); n = strlen(name); val[1] = pos[name[0] - 'a']; s1[1] = val[1]; s2[1] = 0; s3[1] = val[1] * val[1]; for (int i = 1; i < n; i++) { val[i + 1] = pos[name[i] - 'a']; s1[i + 1] = s1[i] + val[i + 1]; s2[i + 1] = s2[i] + i * val[i + 1]; s3[i + 1] = s3[i] + val[i + 1] * val[i + 1]; }}LL getUp(int l, int k, int i) { return (dp[i - 1][l] - s2[l] + s3[l] + l * s1[l]) - (dp[i - 1][k] - s2[k] + s3[k] + k * s1[k]);}LL getDown(int l, int k) { return l - k;}void getDp(int i, int j, int k) { dp[i][j] = dp[i - 1][k] + s2[j] - s2[k] - k * (s1[j] - s1[k]) - (s3[j] - s3[k]);}int cas = 1;void solve() { int head, tail; for (int i = 1; i <= n; i++) dp[1][i] = s2[i] - s3[i]; for (int i = 2; i <= m; i++) { head = tail = 0; que[tail++] = i - 1; for (int j = i; j <= n; j++) { while (head + 1 < tail && getUp(que[head + 1], que[head], i) <= s1[j] * getDown(que[head + 1], que[head])) head++; getDp(i, j, que[head]); while (head + 1 < tail && getUp(j, que[tail - 1], i) * getDown(que[tail - 1], que[tail - 2]) <= getUp(que[tail - 1], que[tail - 2], i) * getDown(j, que[tail - 1])) tail--; que[tail++] = j; } } printf("Case %d: %lld\n", cas++, dp[m][n]);}int main() { int test; scanf("%d", &test); while (test--) { init(); solve(); } return 0;}
- UVA 12594 Naming Babies (斜率优化DP)
- UVA - 12594 Naming Babies(斜率优化)
- uva 12594 斜率优化dp
- UVA 1451 Average 斜率优化
- uva 1451 Average 斜率优化
- UVA 1451 Average(斜率优化)
- UVa 1451 Average——斜率优化
- 斜率优化
- 斜率优化
- 斜率优化
- 斜率优化
- 斜率优化
- 斜率优化
- 斜率优化
- 斜率优化
- 斜率优化
- 斜率优化
- UVA 12524 Arranging Heaps 动态规划 斜率优化
- mac 您需要安装旧 Java SE 6 运行环境才能打开Android Studio,Intellij IDEA
- UVA 1610 Party Games
- 详解Android中AsyncTask的使用
- fzu2198(矩阵乘法模板)
- 微软今天的Windows 10硬件发布会汇总:手机瞬间变PC
- UVA - 12594 Naming Babies(斜率优化)
- Android大数据、断点续传、耗时下载之DownloadManager开发简介(1)
- Git三层同步问题
- 一切为了学员高薪——记传智播客PHP课程体系改革
- jsp乱码问题的讨论
- 模式识别 评价方法 ROC曲线, DET曲线, FPPW, FPPI etc.
- CentOS Linux解决Device eth0 does not seem to be present及设置固定ip
- 80端口被係統佔用,nginx/apache無法啟動,解决方案
- linux/ubuntu下安装nginx时./configure后出现几种错误的解决方法