1. 程式人生 > >poj1695 dp思維 不錯

poj1695 dp思維 不錯

題意:給三輛車,將1~n這n個點依次跑完,也就是說要想到達i+1,必須先到達i,

每兩個點之間都有花費,問最小的話費是什麼。

思路:設dp[i][j][k],為走的最遠的車,次元的車,最近的車在位置i,j,k的時候的最小

花費。具體轉移看程式碼,感覺非常巧妙。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int dp[31][31][31];//分別為走的最遠,次遠,最近的車的位置
int cost[31][31], n;

int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d", &n);

        for(int i=1; i<n; i++){
            for(int j=i+1; j<=n; j++){
                scanf("%d", &cost[i][j]);
            }
        }
        memset(dp, 0x3f, sizeof dp);
        dp[1][1][1]=0;

        for(int i=1; i<=n; i++){//最遠車的位置
            for(int j=1; j<=i; j++){//次遠車的位置
                for(int k=1; k<=j; k++){//最近車的位置
                    dp[i+1][j][k]=min(dp[i+1][j][k], dp[i][j][k]+cost[i][i+1]);
                    dp[i+1][i][k]=min(dp[i+1][i][k], dp[i][j][k]+cost[j][i+1]);
                    dp[i+1][i][j]=min(dp[i+1][i][j], dp[i][j][k]+cost[k][i+1]);
                }
            }
        }
        int mn=INF;
        for(int j=1; j<=n; j++)
            for(int k=1; k<=j; k++)
                mn=min(mn, dp[n][j][k]);
        printf("%d\n", mn);


    }
    return 0;
}