fzoj 1319 Blocks of Stones(DP:水题)
来源:互联网 发布:网络推广广告 编辑:程序博客网 时间:2024/06/16 13:06
Accept: 183 Submit: 732
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
There are n blocks of stones in a line laying on the ground. Now you are to merge these blocks of stones together with the restriction that you can only merge the neighbouring blocks each time. The score you get for each merging is the number of stones the new blocks has.
Before merging, you are allowed to swap a neighbouring block. You are to calculate the minimal score you will get during the merging process, and the swap position.
Input
There are multiple test cases. For each case, the first line contains a integer n(n<=100), representing the number of blocks. The second line contains n integers, representing number of stones in each blocks
Output
For each case, output 2 lines. The first line contains a single integer, representing the minimal score. The second line contains to integers in the form "(k,k+1)", representing the swap position. If there is more than one swap position which can be the minimal score, output the one with the largest k. You should note that : If swap is not needed output "(0,1)".
Sample Input
32 5 13 1 2 5
Sample Output
11(2,3)11(0,1)
Source
chenyan几个月没写DP,真的是废了。。。
这个题很蛋疼的一点就是还存在交换相邻位置的情况
令s[i]保存1-i项石子总数,则交换a[i],a[i+1]即为s[i] = s[i]-a[i]+a[i+1];
枚举n次交换即可,还要注意在一次交换后要恢复原来的情况
状态转移方程为:
dp[i][j] = min(dp[i][k]+dp[k+1,j], dp[i][j])+s[j]-s[i-1];
这个题先写的记忆化搜索,总是超时(后来才知道写的是纯搜索,没有记忆化)
后来又写DP,真是蛋碎了一地!
代码如下:
#include <stdio.h>#include <string.h>#define MAXN 110#define INF 0x7fffffffint a[MAXN], s[MAXN], dp[MAXN][MAXN];int main(void) { int tmp, ans, res, x, n, i, j, k, r, t; while(scanf("%d", &n) != EOF) { s[0] = 0; memset(a, 0, sizeof(a)); for(i=1; i<=n; ++i) { scanf("%d", &a[i]); dp[i][i] = 0; s[i] = s[i-1]+a[i]; } ans = INF; //dp[i][j] = min(dp[i][k]+dp[k+1,j], dp[i][j])+s[j]-s[i-1]; for(t=0; t<n; ++t) { if(t>0) s[t] = s[t]-a[t]+a[t+1]; for(r=1; r<n; ++r) { //printf("s[%d] = %d\n", r, s[r]); for(i=1; i<=n-r; ++i) { j = i+r; dp[i][j] = INF; for(k=i; k<j; ++k) { tmp = dp[i][k]+dp[k+1][j]; dp[i][j] = dp[i][j]>tmp ? tmp : dp[i][j]; } dp[i][j] += s[j]-s[i-1]; } } //printf("dp[1][%d] = %d\n", n, dp[1][n]); tmp = dp[1][n]; if(tmp <= ans) { ans = tmp; x = t; } if(t>0) s[t]=s[t]-a[t+1]+a[t];//恢复变化前的状态,t==0时为最初不交换的状态 else res = dp[1][n]; } if(ans == res) x = 0;//如果和最初的结果一样还要令x=0 printf("%d\n", ans); printf("(%d,%d)\n", x, x+1); }}
我把搜索改进为记忆化搜索代码的如下:
#include <stdio.h>#include <string.h>#define MAXN 110#define INF 0x7fffffffint a[MAXN], s[MAXN], dp[MAXN][MAXN];int search(int i, int j) { int ans, tmp, k; if(dp[i][j] != -1) return dp[i][j]; ans = INF; for(k=i; k<j; ++k) { tmp = search(i, k)+search(k+1, j); ans = ans > tmp ? tmp : ans; } return dp[i][j] = ans + s[j]-s[i-1];}int main(void) { int tmp, ans, res, x, n, i; while(scanf("%d", &n) != EOF) { s[0] = 0; memset(dp, -1, sizeof(dp)); memset(a, 0, sizeof(a)); for(i=1; i<=n; ++i) { scanf("%d", &a[i]); s[i] = s[i-1]+a[i]; dp[i][i] = 0; } x = 0; search(1, n); ans = res = dp[1][n]; for(i=1; i<n; ++i) { s[i] = s[i]-a[i]+a[i+1]; search(1, n); if(ans >= dp[1][n]) { ans = dp[1][n]; x = i; } s[i] = s[i]-a[i+1]+a[i]; memset(dp, -1, sizeof(dp)); for(int j=1; j<=n; ++j) dp[j][j] = 0; } if(res == ans) x = 0; printf("%d\n", ans); printf("(%d,%d)\n", x, x+1); }}
0 0
- fzoj 1319 Blocks of Stones(DP:水题)
- FOJ 1319 Blocks of Stones
- FOJ 1319 Blocks of Stones[ 区间 ]
- Problem 1327 Blocks of Stones II
- fzoj 1523 A Version of Nim(DP)
- FZOJ 1640 place blocks
- FZOJ--2221-- RunningMan(水题)
- fzoj 2156 DP
- fzoj 2113数位dp
- [POJ1390]Blocks(dp)
- fzoj 1342 Tight Words(DP:递推)
- fzoj 1381 Regular Expressions(DP:字符串匹配加强版)
- FZOJ 1026: [SCOI2009]windy数(数位dp)
- POJ2978-Colored stones(状压dp)
- Pangu and Stones(区间dp)
- FZOJ--2212--Super Mobile Charger(水题)
- UVa 10559 Blocks(DP)
- [POJ1390]Blocks(区间dp)
- [Lua]mac 上安装lua
- PHP+MYSQL会员系统的开发实例教程
- 正则表达式(括号)、[中括号]、{大括号}的区别小结
- 一种stm32架构
- AC自动机模板 LA4670
- fzoj 1319 Blocks of Stones(DP:水题)
- 11gr2 RAC安装INS-35354问题,remote节点识别不了
- 分治法求数组最大连续子序列的和
- OpenGL直观固管图
- poj 2886(线段树)
- hdu 1561 The more, The Better 树形dp
- 简单数据删除(DROP TABLE语句和DELETE)
- 范式理伦
- <开发与进阶> 读书笔记 --- coredata 补充