一列石子合并问题(动态规划)

diaoxue 2007-12-23 07:20:49
程序没有结果,帮忙看看
/*m[i][j]={0 i=j;min{m[i][k-1]+m[k][j]+w(i,j)} i<j}*/
#include <iostream>
using namespace std;
const int N=4;
int a[N]={4,4,5,9};
int m[N][N]={0};
int s[N][N]={0};
int Sum(int a[],int i,int j)//最后一次合并的得分
{
int temp=0;
for(int k=i;k<=j;k++)
{
temp+=a[k];
}
return temp;
}

void Stone()//动态规划求最小得分
{
int i,j,r,k,t;
for(i=0;i<N;i++)
m[i][i]=0;
for(r=1;r<N;r++)
{
for(i=0;i<N-r;i++)
{
j=i+r;
for(k=i+1;k<j;k++)
{
t=m[i][k-1]+m[k][j]+Sum(a,i,j);
if(t<m[i][j])
{
m[i][j]=t;
s[i][j]=k;
}
}
}
}
}

int main()
{
Stone();
cout<<m[0][N-1]<<endl;
return 0;
}
...全文
1406 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
xkey 2009-11-19
  • 打赏
  • 举报
回复
这是我写的代码
#include<iostream>
using namespace std;
int sum(int p[],int m,int n)
{
int ans=0;
for(int i=m;i<=n;i++)
ans+=p[i];
return ans;
}
//类似与矩阵连乘
int main()
{
int n,i,j,k,r,t,temp,p[100],m[100][100];;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&p[i]);
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;
temp=sum(p,i,j);
m[i][j]=m[i+1][j]+temp;
for(k=i+1;k<j;k++)
{
t=m[i][k]+m[k+1][j]+temp;
if(t>m[i][j])//只要把这里的>改为<就变成求最小合并了
m[i][j]=t;
}
}
}
printf("%d\n",m[1][n]);
return 7;
}
zhanglei100 2008-09-08
  • 打赏
  • 举报
回复
可以把原题发过来吗,我想用MATLAB软件可以实现。用动态规划求极值
cymandhxl 2008-09-05
  • 打赏
  • 举报
回复
没看懂。因为只要石子数不便的话。分数好像不会便啊
C1053710211 2007-12-29
  • 打赏
  • 举报
回复
算法没有问题,解决你三楼的问题你定义的N是6,显然在这个循环中

for(int r=2;r <=n;r++)
{
for(int i=1;i <=n-r+1;i++)
{
int j=i+r-1;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i;
for(int k=i+1;k <j;k++)
{
int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(t <m[i][j])
{
m[i][j]=t;
s[i][j]=k;
}
}
}
}


当r=n,i=1时,j=n,那么你的p数组就会访问下界为6的数组,数组越界,所以结果不对,
建议你将N改的大一点试试,再不好用发帖告诉我,我再改
diaoxue 2007-12-29
  • 打赏
  • 举报
回复
石子合并问题解决,结果也时正确的
但是矩阵连乘还是不行,帮忙看看啊
石子合并问题的程序:(求最大的)
/*m[i][j]={0 i=j;min{m[i][k-1]+m[k][j]+w(i,j)} i<j}*/
#include <iostream>
using namespace std;

const int N=4;
int a[N]={4,4,5,9};
int m[N][N]={0};
int s[N][N]={0};
int Sum(int a[],int i,int j)//最后一次合并的得分
{
int temp=0;
for(int k=i;k<=j;k++)
{
temp+=a[k];
}
return temp;
}

void Stone()//动态规划求最小得分
{
int i,j,r,k,t;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
m[i][j]=0;
for(i=0;i<N;i++)
m[i][i]=0;
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
cout<<m[i][j]<<"\t";
cout<<endl;
}
for(r=1;r<N;r++)
{
for(i=0;i<N-r;i++)
{
j=i+r;
for(k=i+1;k<=j;k++)
{
t=m[i][k-1]+m[k][j]+Sum(a,i,j);
if(t>m[i][j])
{
m[i][j]=t;
s[i][j]=k;
}
}
}
}
}

int main()
{
Stone();
cout<<m[0][N-1]<<endl;
return 0;
}
diaoxue 2007-12-29
  • 打赏
  • 举报
回复
那你看看这个矩阵连乘程序,只能输出两格正确结果
流程差不多
#include<iostream.h>
#define N 6
void MatrixChain(int *p,int n,int m[N][N],int s[N][N]);
//int Traceback(int i,int j,int s[N][N]);
int main()
{
int p[]={30,35,15,5,10,20,25};
// for(int k=0;k<7;k++)
// cout<<p[k]<<" ";
int n=6,i=0,j=0;
int m[6][6];
int s[6][6];
MatrixChain(p,n,m,s);
for(i=1;i<=N;i++)
{
for(j=1;j<=N;j++)
{
if(i<=j)
cout<<m[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
// int i=1,j=6;
// Traceback(i,j,s);
return 0;
}
void MatrixChain(int *p,int n,int m[N][N],int s[N][N])
{
for(int i=1;i<=n;i++)m[i][i]=0;
for(int r=2;r<=n;r++)
{
for(int i=1;i<=n-r+1;i++)
{
int j=i+r-1;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i;
for(int k=i+1;k<j;k++)
{
int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(t<m[i][j])
{
m[i][j]=t;
s[i][j]=k;
}
}
}
}
/* for(i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
{
if(i<=j)
cout<<m[i][j]<<" ";
}
cout<<endl;
}*/
}
/*int Traceback(int i,int j,int s[N][N])
{
if(i==j)return -1;//cout<<"no-op"<<endl;
Traceback(i,s[i][j],s);
Traceback(s[i][i]+1,j,s);
cout<<"Multiply A"<<i<<","<<s[i][j];
cout<<"and A"<<(s[i][j]+1)<<","<<j<<endl;
return 0;
}*/
diaoxue 2007-12-29
  • 打赏
  • 举报
回复
石子合并问题,还有个问题就是环型的石子合并怎么处理
diaoxue 2007-12-29
  • 打赏
  • 举报
回复
我改了下,还是有问题,第一行和第一列不是正确的,
我想时循环时的范围出了问题
我改了下,还是有问题,第一行和第一列
#include <iostream>
#include <iomanip>
using namespace std;
//#define N 6
const int N=6;
void MatrixChain(int *p,int n,int m[N][N],int s[N][N]);
//int Traceback(int i,int j,int s[N][N]);
int main()
{
int p[]={30,35,15,5,10,20,25};
// for(int k=0;k<7;k++)
// cout<<p[k]<<" ";
int n=6,i=0,j=0;
int m[6][6]={0};
int s[6][6]={0};
MatrixChain(p,n,m,s);
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
// if(i<=j)
// cout<<m[i][j]<<" ";
cout<<setw(5)<<m[i][j];
}
cout<<endl;
}
cout<<endl;
// int i=1,j=6;
// Traceback(i,j,s);
return 0;
}
void MatrixChain(int *p,int n,int m[N][N],int s[N][N])
{
for(int i=0;i<n;i++)
m[i][i]=0;
for(int r=1;r<n;r++)
{
for(int i=0;i<n-r;i++)
{
int j=i+r;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i;
for(int k=i+1;k<j;k++)
{
int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(t<m[i][j])
{
m[i][j]=t;
s[i][j]=k;
}
}
}
}
/* for(i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
{
if(i<=j)
cout<<m[i][j]<<" ";
}
cout<<endl;
}*/
}
/*int Traceback(int i,int j,int s[N][N])
{
if(i==j)return -1;//cout<<"no-op"<<endl;
Traceback(i,s[i][j],s);
Traceback(s[i][i]+1,j,s);
cout<<"Multiply A"<<i<<","<<s[i][j];
cout<<"and A"<<(s[i][j]+1)<<","<<j<<endl;
return 0;
}*/
C1053710211 2007-12-27
  • 打赏
  • 举报
回复
不知道你的问题是什么,但是你这程序

for(k=i+1;k <j;k++)
{
t=m[i][k-1]+m[k][j]+Sum(a,i,j);
if(t<m[i][j])
{
m[i][j]=t;
s[i][j]=k;
}
}

是没有用的,因为m[i][j]初始为0,任何t=m[i][k-1]+m[k][j]+Sum(a,i,j)都不可能小于m[i][j]
所以if里的程序段不可能被执行到,所以最后肯定是0.
diaoxue 2007-12-26
  • 打赏
  • 举报
回复
大家帮忙看下啊
我写了矩阵连乘时也不对

33,009

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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