动态规划问题,高手请进。

fdg个sggggg 2008-11-25 08:25:18
在一个圆形操场的四周摆放着N堆石子(N <=100),现要将石子有次序地合并成一堆. 规定每次只能选取相邻的两堆合并成新的一堆,并将新的一堆的石子数记为该次合并的得分. 编写一程序,读入堆栈数N及每堆栈的石子数( <=20).
(1)选择一种合并石子的方案,使用权得做N-1次合并,得分的总和最小;
(2)选择一种合并石子的方案,使用权得做N-1次合并,得分的总和最大;
这是我自己做的请帮慢改正一下吧,,错的地方不会啊,实在是晕了。
请在我的基础上帮我改改,谢了。
#include <iostream>
#include <stdlib.h>

using namespace std;
long int date[101];
long int f[101][101];
int a[101];
int max(int a,int b);
void fac(int a[],int N);
int main(int argc, char *argv[])
{
int N;
cout < <"请输入石子的堆数:" < <endl;
cin>>N;
cout < <"请输入各堆的石子数:" < <endl;
for(int i=1;i <=N;i++)
cin>>date[i];
for(int i=1;i <=N;i++)
f[i][1]=date[i];
for(int j=2;j <=N;j++)
for(int i=1;i <=N;i++)
{
for(int k=1;k <=j-1;k++)
f[i][j]=max(f[i][k]+f[(i+k+1)%N+1][j-k]); //这就错了,还有错的地方
}
for(int i=1;i <=N;i++)
a[i]=f[i][N];
fac(a,N);
cout < <"最大得分为:" < <a[1] < <endl;
system("PAUSE");
return 0;
}
int max(int a,int b)
{
if(a>=b) return a;
else
return b;
}
void fac(int a[],int N)
{
for(int i=1;i <N-1;i++)
for(int j=1;j <N-1-i;j++)
{
if(a[j] <a[j+1])
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
...全文
117 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
fdg个sggggg 2008-11-26
  • 打赏
  • 举报
回复
谢谢了 ,问了挺长时间了终于有正确的答案了, 我还有一个帖子,问题也是一样的,你把你的代码复制过去吧,那个100分呢,我把分都给你,那些人说的都是废话,不会就瞎写,
就呆在云上 2008-11-25
  • 打赏
  • 举报
回复
#include <iostream> 
#include <stdlib.h>

using namespace std;

int main(int argc, char *argv[])
{
int n,i,j,k,p,sum=0,m,max=0,*a,**f,t;
cout<<"请输入石子的堆数:";
cin>>n;
a=new int[2*n];//动态数组存储单元
a[0]=0;
cout<<"请输入中每堆石子的个数:"<<endl;
for(i=1;i<=n;i++)
cin>>a[i];//输入石子各堆数的个数
for(t=1;t<n;t++)
{
a[n+t]=a[t];
}//形成一个看似循环的数组
for(t=1;t<2*n;t++)
f=new int *[n+1];//为动态二维数组分配内存单元
for(int i=0;i<=n;i++)
f[i]=new int [n+1];
for(i=0;i<=n;i++)//为动态二维数组初始化为0
for(j=0;j<=n;j++)
f[i][j]=0;
for(i=1;i<=n;i++)//数组第一列赋值为0(经分析得)
f[i][1]=0;
for(j=2;j<=n;j++)//为数组其他元素赋值
{
for(i=1;i<=n;i++)
{
max=0;
for(k=1;k<=j-1;k++)
{
m=f[i][k]+f[(i+k-1)%n+1][j-k];
if(max<m)
max=m;
}
sum=0;
for(p=i;p<=i+j-1;p++)//最终每堆石子都将有两堆石子合并
sum=sum+a[p];
f[i][j]=sum+max;
}
}
max=f[1][n];//对最后一列寻找最大值即为最大得分
for(i=1;i<=n;i++)
{
if(max<f[i][n])
max=f[i][n];
}
cout<<"最大得分为:"<<max;
system("PAUSE");
return 0;
}//应该是正确的吧
wudeshou82666 2008-11-25
  • 打赏
  • 举报
回复
Up
BaihowFF 2008-11-25
  • 打赏
  • 举报
回复
额...好像还是有点问题...额...我信息学的书早扔不见了...也不知道方程对不对...
BaihowFF 2008-11-25
  • 打赏
  • 举报
回复
石子并归应该还有一个sum数组才对啊...我已经改了...加了一个sum数组进去...而且你的方程有点问题...用max也有问题...怎么就给一个参数...反正改好了...看看吧...

long int date[101];
long int f[101][101];
long int sum[101][101];
int a[101];
int max(int a,int b);
void fac(int a[],int N);
int main(int argc, char *argv[])
{
int N;
cout <<"请输入石子的堆数:" <<endl;
cin>>N;
cout <<"请输入各堆的石子数:" <<endl;
for(int i=1;i <=N;i++)
cin>>date[i];
for(int i=1;i <=N;i++)
f[i][1]=date[i];

for(int j=2;j <=N;j++)
for(int i=1;i <=N;i++)
{
sum[i][j] = date[i] + sum[i % N + 1][j-1];
}

for(int j=2;j <=N;j++)
for(int i=1;i <=N;i++)
{
for(int k=1;k <=j-1;k++)
{
f[i][j]=max(f[i][k]+f[i+k][j-k]+sum[i][j],f[i][j]);
}
}
for(int i=1;i <=N;i++)
a[i]=f[i][N];
fac(a,N);
cout <<"最大得分为:" <<a[1] <<endl;
system("PAUSE");
return 0;
}
int max(int a,int b)
{
if(a>=b) return a;
else
return b;
}
void fac(int a[],int N)
{
for(int i=1;i <N-1;i++)
for(int j=1;j <N-1-i;j++)
{
if(a[j] <a[j+1])
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧