UVA 348

来源:互联网 发布:装修找熟人好不好知乎 编辑:程序博客网 时间:2024/05/15 12:59

  大致题意为给定一个矩阵序列,求最小运算次数的次序。记忆化搜索,再根据dp结果查找路径即可,设状态dp(i,j)为第i个矩阵到第j个矩阵的最小运算次数,那么状态转移方程为dp(i,j)=min{dp(i,k)+dp(k+1,j)+r(i)*c(k)*c(j)},其中i<=k<j,r(i)为第i个矩阵的行数,c(i)为第i个矩阵的列数,那么一遍dp之后即可得到最小计算次数,路径的记录可以每到达一个区间,就将区间括起来,根据之前的计算,找到最小划分,递归进去即可。

#include <iostream>#include <algorithm>#include <cstring>using namespace std;int r[11],c[11],pre[11]={0},post[11]={0};int ans[11][11];int dp(int i,int j){if(ans[i][j]!=0x7FFFFFFF) return ans[i][j];for(int k=i;k<j;k++){ans[i][j]=min(ans[i][j],dp(i,k)+dp(k+1,j)+r[i]*c[k]*c[j]);}return ans[i][j];}void gp(int i,int j){if(i==j) return ;pre[i]++;post[j]++;int p,k;for(k=i;k<j;k++){if((ans[i][k]+ans[k+1][j]+r[i]*c[k]*c[j])==ans[i][j])p=k;}gp(i,p);gp(p+1,j);}int main(){int n,ca=1;while(cin>>n&&n){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) ans[i][j]=0x7FFFFFFF;for(int i=1;i<=n;i++) {cin>>r[i]>>c[i];pre[i]=post[i]=0;ans[i][i]=0;}dp(1,n);gp(1,n);cout<<"Case "<<ca++<<": ";for(int i=1;i<=n;i++){for(int j=1;j<=pre[i];j++) cout<<'(';cout<<'A'<<i;for(int j=1;j<=post[i];j++) cout<<')';if(i!=n) cout<<" x ";}cout<<endl;}return 0;}


 

0 0
原创粉丝点击