Brush Mode --- Nyoj 737 分类: Brush Mode 2014-03-25 08:10 202人阅读 评论(0) 收藏

石子合并(一)

时间限制: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\n",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\n",num[0][n-1]);
    }  
	return 0;
}        


版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2014-03-25 08:10  天I火  阅读(109)  评论(0编辑  收藏  举报