最优矩阵链乘

主要大区间化为小区间……

先小区间求值……

状态转移方程 f(i,j) = min{ f(i,k) + f(k+1,j) + p[i-1]p[k]p[j] };

poj 1651 http://poj.org/problem?id=1651

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <cstdlib>



const int MAXN = 100 + 10;

const double ESP = 10e-8;

const double Pi = atan(1.0) * 4;

const int INF = 0xfffffff;

const int MOD = 10000007;



using namespace std;



int n;

int dp[MAXN][MAXN];

int c[MAXN];



void multiplication(){

    for(int i = 0;i < n;i++){

        dp[i][i] = 0;

    }

    for(int l = 2;l < n;l++){

        for(int i = 1;i < n-l+1;i++){

            int j = i+l-1;

            dp[i][j] = INF;

            for(int k = i;k < j;k++){

                int tmp = dp[i][k] + dp[k+1][j] + c[i-1] * c[k] * c[j];

                dp[i][j] = min(dp[i][j],tmp);

            }

        }

    }

}

int main(){

    //freopen("input.txt","r",stdin);

    scanf("%d",&n);

    for(int i = 0;i < n;i++){

        scanf("%d",&c[i]);

    }

    multiplication();

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

    return 0;

}
View Code

 poj 1179  http://poj.org/problem?id=1179

大致题意:

给你一个环,点是数字,边是运算,你断掉其中一条边之后,然后可以把相连的两个点经边的运算合并成一个点,求最大值

解题思路,枚举断的点然后进行矩阵相乘。

题解……1 我抄都抄不会的代码…… 抄来代码就是运行不对…… Orz ……http://m.blog.csdn.net/blog/u012962816/26822959

题解……2 http://www.tuicool.com/articles/Jj2Avi

在第一个自己笨到抄不对的时候,参考了题解2

然后从新自己写了一下……

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <cstdlib>



const int MAXN = 100 + 10;

const double ESP = 10e-8;

const double Pi = atan(1.0) * 4;

const int INF = 0xffffff;

const int MOD = 10000007;



using namespace std;

char edge[MAXN];

int vet[MAXN];

int dp1[MAXN/2][MAXN/2],dp2[MAXN/2][MAXN/2];

int fin[MAXN];

int N;

int main(){

   // freopen("input.txt","r",stdin);

    int ans = -INF;

    scanf("%d",&N);

    for(int i = 0;i < N;i++){

        getchar();

        scanf("%c %d",&edge[i],&vet[i]);

    }

    for(int t = 0;t < N;t++){ //从t位置为起点

        for(int i = 0;i < N;i++){  //进行矩阵的初始化

            dp1[i][i] = vet[(t+i)%N];

            dp2[i][i] = dp1[i][i];

        }  

        for(int l = 2;l <= N;l++){     //j-i的长度

            for(int i = 0;i < N-l+1;i++){ 

                int maxv = -INF;

                int minv = INF;

                int j = i+l-1;

                for(int k = i;k < j;k++){

                    if(edge[(k+1+t)%N] == 't'){   //这里也要相应的改变

                        maxv = max(maxv,dp1[i][k] + dp1[(k+1)%N][j]);

                        minv = min(minv,dp2[i][k] + dp2[(k+1)%N][j]);

                    }

                    else{

                        maxv = max(maxv,dp1[i][k] * dp1[(k+1)%N][j]);

                        maxv = max(maxv,dp2[i][k] * dp2[(k+1)%N][j]); //负负得正

                        minv = min(minv,dp1[i][k] * dp2[(k+1)%N][j]); //正负相乘

                        minv = min(minv,dp2[i][k] * dp2[(k+1)%N][j]);

                        minv = min(minv,dp2[i][k] * dp1[(k+1)%N][j]);  //正负相乘

                    }

                }

                dp1[i][j] = maxv;  //进行赋值

                dp2[i][j] = minv;

            }

        }

        ans = max(ans,dp1[0][N-1]);

        fin[t] = dp1[0][N-1];

    }

    printf("%d\n",ans);

    for(int i = 0;i < N;i++){

        if(fin[i] == ans){

            printf("%d ",i+1);

        }

    }

    printf("\n");

    return 0;

}

 uva 10003 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=847&problem=944&mosmsg=Submission+received+with+ID+15274403

d(i,j)为 i - j 的最优费用,则 d(i,j) - min{ d(i,k) + d(k,j)  + a[j] - a[i] };

先小区间求值……

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <cstdlib>



const int MAXN = 1000 + 10;

const double ESP = 10e-8;

const double Pi = atan(1.0) * 4;

const int INF = 0xffffff;

const int MOD = 10000007;



using namespace std;

int a[MAXN];

int dp[MAXN][MAXN];

int main(){

   // freopen("input.txt","r",stdin);

    int len;

    while(~scanf("%d",&len) && len){

        int n;

        scanf("%d",&n);

        for(int i = 1;i <= n;i++){

            scanf("%d",&a[i]);

        }

        memset(dp,0,sizeof(dp));

        a[0] = 0;

        a[n+1] = len;

        for(int l = 2;l <= n+1;l++){

            for(int i = 0;i+l <= n+1;i++){

                int j = i+l;

                dp[i][j] = INF;

                for(int k = i+1;k < j;k++){

                    int tmp = dp[i][k] + dp[k][j] + a[j]-a[i];

                    if(tmp < dp[i][j]){

                        dp[i][j] = tmp;

                    }

                }

            }

        }

        printf("The minimum cutting is %d.\n",dp[0][n+1]);

    }

    return 0;

}

 

你可能感兴趣的:(矩阵)