标签:
Blocks of Stones
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
Output
Sample Input
Sample Output
阶段:以归并石子的长度为阶段,一共有n-1个阶段。
状态:每个阶段有多少堆石子要归并,
当归并长度为2时,有n-1个状态;
当归并长度为3时,有n-2个状态;
当归并长度为n时,有1个状态。
决策:当归并长度为2时,有1个决策;
当归并长度为3时,有2个决策;
当归并长度为n时,有n-1个决策。
代码:
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; const int INF = 1 << 30; const int N = 205; int dp[N][N]; int sum[N]; int a[N]; int getMinval(int a[],int n) { for(int i=0;i<n;i++) dp[i][i] = 0; for(int v=1;v<n;v++) { for(int i=0;i<n-v;i++) { int j = i + v; dp[i][j] = INF; int tmp = sum[j] - (i > 0 ? sum[i-1]:0); for(int k=i;k<j;k++) dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j] + tmp); } } return dp[0][n-1]; } int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) scanf("%d",&a[i]); sum[0] = a[0]; for(int i=1;i<n;i++) sum[i] = sum[i-1] + a[i]; int x=0,y=1; int flag=1; int ans=getMinval(a,n); for(int i=0;i<n-1;i++) { sum[i]=sum[i]-(a[i]-a[i+1]); int tmp=getMinval(a,n); if(flag) { if(tmp<ans) { ans=tmp; x=i+1; y=i+2; flag=0; } } else{ if(tmp<=ans) { ans=tmp; x=i+1; y=i+2; } } sum[i]=sum[i]+(a[i]-a[i+1]); } printf("%d\n(%d,%d)\n",ans,x,y); } return 0; }
FOJ 1319 Blocks of Stones[ 区间 ]
标签:
原文地址:http://blog.csdn.net/code_or_code/article/details/42781031