MV Maker [DP]

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2901

一般DP复杂度 O(L*N^2), 分段计算 O(lgL*N*N)

View Code
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <string>
#include <cstring>
#include <algorithm>

int f_min(int x,int y) {if(x>y) return y; else return x;}
int f_max(int x,int y) {if(x>y) return x; else return y;}
using namespace std;

const int MM = 1111111;
//typedef __int64 int64;
typedef long long int64;
//const __int64 maxint = 0x3f3f3f3f;
const long long maxint = 10000000000000;
string str[MM];
int64 N,M,L;
int64 maze[111][111];
int64 d[2][111];
int64 dp[20][111][111];

void get_data() {
    int64 i,j,k;
    scanf("%lld%lld",&N,&L);
    for(i=1;i<=N;i++) {
        for(j=1;j<=N;j++) {
            scanf("%lld",&dp[0][i][j]);
        }
    }
    L--;
}
void debug(int len) {
    int i,j,k;
    for(i=0;i<=len;i++) {
        printf("%d\n",i);
        for(j=1;j<=N;j++) {
            for(k=1;k<=N;k++) {
                printf("%d ",dp[i][j][k]);
            }
            printf("\n");
        }
    }
}
void solve() {
    int64 i,j,k,t;
    int64 now=0, pre=1, len=0;
    for(i=0;(1<<(i+1))<=L;i++) {
        for(j=1;j<=N;j++) {
            for(k=1;k<=N;k++) {
                dp[i+1][j][k]=-maxint;
                for(t=1;t<=N;t++) {
                    if((dp[i][j][t]+dp[i][t][k])>dp[i+1][j][k]) {
                        dp[i+1][j][k]=dp[i][j][t]+dp[i][t][k];
                    }
                }
            }
        }
        len++;
    }
//    debug(len);
    memset(d[now],0,sizeof(d[now]));
    for(i=len;i>=0;i--) {
        if(L < (1<<i)) continue;
        L-=(1<<i);
        for(j=1;j<=N;j++) d[pre][j]=-maxint;
        for(j=1;j<=N;j++) {
            for(k=1;k<=N;k++) {
                if(d[pre][k]<(d[now][j]+dp[i][j][k])) d[pre][k]=d[now][j]+dp[i][j][k];
            }
        }
        now=pre, pre^=1;
    }
    int64 ans=-maxint;
    for(i=1;i<=N;i++) {
        if(d[now][i]>ans) ans=d[now][i];
    }
    printf("%lld\n",ans);
}
int main() {
    int ca; scanf("%d",&ca);
    while(ca--) get_data(),solve();
    return 0;
}
原文地址:https://www.cnblogs.com/zhang1107/p/2973375.html