您的位置:首页 > 其它

不能移动的石子合并

2013-06-12 13:43 232 查看
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]
);

m=stoneMax1(a,n,m);

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

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: