不能移动的石子合并
来源:互联网 发布:eviews怎么导入数据 编辑:程序博客网 时间:2024/06/06 02:33
时间限制: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;
}
- 不能移动的石子合并
- 不能移动的石子合并
- 不能移动的石子合并问题
- 11078 不能移动的石子合并
- 【动态规划】不能移动的石子合并
- 11078 不能移动的石子合并(dp)
- 可以移动的石子合并
- 11079 可以移动的石子合并
- 11079 可以移动的石子合并
- 11079 可以移动的石子合并(贪心)
- 不能移动的石头合并问题
- 石子合并的GarsiaWachs算法
- -----区间DP 石子的合并
- 石子-石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- spring和hibernate整合
- Longest Ordered Subsequence
- wwdc 2013
- 最长公共子字符串
- PBO
- 不能移动的石子合并
- 【修炼十一】联调
- 最大长方体问题
- CArray类中GetAt()函数与ElementAt()函数的区别
- 区间相交问题
- MySQL学习记录(约束+语法+演示分析)三
- 可以移动的石子合并
- 删数问题
- 整除15 问题