石子合并(一)
时间限制:1000 ms | 内存限制:65535 KB
难度:3
- 描述
- 有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
- 输入
- 有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开 - 输出
- 输出总代价的最小值,占单独的一行
- 样例输入
-
3 1 2 3 7 13 7 8 16 21 4 18
- 样例输出
-
9 239
超时代码,暴力模拟:
#include<stdio.h> int min = 0; void find(int s[],int k,int d){ int i, j, v, c; int b[100]; if(k==1 && d<=min) min = d; for(v=0;v<k;v++) b[v] = s[v]; for(i=0;i<k-1;i++){ for(v=0;v<k;v++){ s[v] = b[v]; } s[i]=s[i]+s[i+1]; c = d + s[i]; for(j=i+2;j<k;j++){ s[j-1]=s[j]; } find(s,k-1,c); } } int main(){ int num[100],sum[100]; int n, i; while(~scanf("%d",&n)){ for(i=0;i<n;i++){ scanf("%d",&num[i]); min+=num[i]; } min*=n; find(num,n,0); printf("%d ",min); } return 0; }
3重循环的DP= =通过了:
-
#include<stdio.h> #include<string.h> int min(int a,int b){ return a>b?b:a; } int sumd(int a[],int ai,int bi){ int i, c=0; for(i=ai;i<=bi;i++) c+=a[i]; return c; } int main(){ int num[210][210]; int cur[210]; int sum[210][210]; int n, i, j, k; while(~scanf("%d",&n)){ memset(num,0,sizeof(num)); memset(cur,0,sizeof(cur)); for(i=0;i<n;i++) scanf("%d",&cur[i]); for(i=0;i<n;i++) for(j=i;j<n;j++) sum[i][j]=sumd(cur,i,j); for(i=1;i<n;i++){ for(j=0;j<n-i;j++){ for(k=0;k<i;k++){ if(num[j][j+i]) num[j][j+i] = min((num[j][j+k]+num[j+k+1][j+i]+sum[j][j+i]),num[j][j+i]); else num[j][j+i] = (num[j][j+k]+num[j+k+1][j+i]+sum[j][j+i]); } } } printf("%d ",num[0][n-1]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。