不能移动的石子合并

来源:互联网 发布:eviews怎么导入数据 编辑:程序博客网 时间:2024/06/06 02:33
11078 不能移动的石子合并
时间限制:1000MS 内存限制:65535K 提交次数:0 通过次数:0
语言: not limited
描述
做如下两个模型的石子合并,如下模型石子都不能移动出列,且合并都仅发生在相邻两堆石子中:
(1)第一个模型:一行排列且相邻合并
有n堆石子形成一行(a1,a2,…,an,ai为第i堆石子个数),相邻两堆可合并,合并的分值为新堆的石子数。求合并为一堆的最低得分和最高得分。
(2)第二个模型:一圈排列且相邻合并
有n堆石子形成首位相连的一个环形(a1,a2,…,an,ai为第i堆石子个数,an和a1相邻),相邻两堆可合并,合并的分值为新堆的石子数。求合并为一堆的最低得分和最高得分。
例如4堆石子,每堆石子个数:9 4 4 5
若排成一行,最小分值:(4+4)+(8+5)+(9+13)=43,最大分值:(9+4)+(13+4)+(17+5)=52。
若排成圈状,最小分值:(4+4)+(8+5)+(9+13)=43,最大分值:(9+5)+(14+4)+(18+4)=54。
输入格式
两行。第一行n,第二行a1 a2 … an,每个ai(1<=i<=n)表示第i堆石子的个数,n<=100
输出格式
19
两行。第一行是第一个模型的最低得分和最高得分,中间空格相连,第二行是第二个模型的最低得分和最高得分,中间空格相连。
输入样例
4
9 4 4 5
输出样例
43 52
43 54

20



-----------------------------------------------------------

11078 不能移动的石子合并                      (动态规划)

#include<stdio.h>

#include<malloc.h>

int** stoneMin1(int *a,int n,int** m)

{

int i,j,k,r,p,t,sum;

for(i=1;i<=n;i++) m[i][i]=0;

for(r=2;r<=n;r++)

for(i=1;i<=n-r+1;i++){

j=i+r-1;

sum=0;

for(p=i;p<=j;p++)

sum+=a[p];

m[i][j]=m[i+1][j]+sum;

for(k=i+1;k<j;k++){

t=m[i][k]+m[k+1][j]+sum;

if(t<m[i][j]){m[i][j]=t;}

}

}

return m;

}

int** stoneMax1(int *a,int n,int** m)

{

int i,j,k,r,p,t,sum;

for(i=1;i<=n;i++) m[i][i]=0;

for(r=2;r<=n;r++)

for(i=1;i<=n-r+1;i++){

j=i+r-1;

sum=0;

for(p=i;p<=j;p++)

sum+=a[p];

m[i][j]=m[i+1][j]+sum;

for(k=i+1;k<j;k++){

t=m[i][k]+m[k+1][j]+sum;

if(t>m[i][j]){m[i][j]=t;}

}

}

return m;

}

int** ADD(int *a,int n,int** sum)

{

int i,j,t;

for(i=1;i<=n;i++)

for(j=0;j<n;j++)

{

sum[i][j]=0;

if(i+j<=n)

for(t=i;t<=i+j;t++)

sum[i][j]+=a[t];

else

{ for(t=i;t<=n;t++)

sum[i][j]+=a[t];

for(t=1;t<=(i+j)%n;t++)

sum[i][j]+=a[t];

}

}

return sum;

}

int** stoneMin2(int *a,int n,int** f,int **sum)

{

int i,j,k,r,t;

for(i=1;i<=n;i++) f[i][0]=0;

for(j=1;j<n;j++)

{

for(i=1;i<=n;i++){

int flag=1;

for(k=0;k<j;k++){

r=i+k+1;

if(r!=n)

r=r%n;

t=f[i][k]+f[r][j-k-1]+sum[i][j];

if(flag==1) {f[i][j]=t;

flag=0;}

if(t<f[i][j]){f[i][j]=t;}

}

}

}

return f;

}

int** stoneMax2(int *a,int n,int** f,int **sum)

{

int i,j,k,r,t;

for(i=1;i<=n;i++) f[i][0]=0;

for(j=1;j<n;j++)

{

for(i=1;i<=n;i++){

int flag=1;

for(k=0;k<j;k++){

r=i+k+1;

if(r!=n)

r=r%n;

t=f[i][k]+f[r][j-k-1]+sum[i][j];

if(flag==1){ f[i][j]=t;

flag=0;}

if(t>f[i][j]){f[i][j]=t;}

}

}

}

return f;

}

int main()

{

int n,*a,i,**m,**sum,min,max;

{

scanf("%d",&n);}while(n<0||n>100);

a=(int*)malloc((n+1)*sizeof(int));

m=(int**)malloc((n+1)*sizeof(int*));

sum=(int**)malloc((n+1)*sizeof(int*));

for(i=1;i<=n;i++)

{

m[i]=(int*)malloc((n+1)*sizeof(int));

sum[i]=(int*)malloc((n+1)*sizeof(int));

}

for(i=1;i<=n;i++)

scanf("%d",a+i);

m=stoneMin1(a,n,m);

printf("%d ",m[1][n]);

m=stoneMax1(a,n,m);

printf("%d\n",m[1][n]);

sum=ADD(a,n,sum);

m=stoneMin2(a,n,m,sum);

min=m[1][n-1];

for(i=2;i<=n;i++)

{

if(m[i][n-1]<min) min=m[i][n-1];

}

printf("%d ",min);

m=stoneMax2(a,n,m,sum);

max=m[1][n-1];

for(i=2;i<=n;i++)

{

if(m[i][n-1]>max) max=m[i][n-1];

}

printf("%d\n",max);

return 0;

}




原创粉丝点击