您的位置:首页 > 其它

poj 1695 DP

2014-02-25 13:15 239 查看
AC代码如下:

/*
dp[i][j][k] 表示最前面一个在i,其他两个在j k是的最少时间  i>=j>=k
然后向前更新即可
1A 0MS 好爽!
*/

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

#define MAX 0x3f3f3f3f

int dp[31][31][31];
int dis[31][31];
int N;

int main(){
int T;

cin >> T;
while( T-- ){
cin >> N;
memset( dis, 0, sizeof( dis ) );
for( int i = 1; i <= N; i++ ){
for( int j = i + 1; j <= N; j++ ){
cin >> dis[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] + dis[i][i+1] );//i走到i+1
dp[i+1][i][k] = min( dp[i+1][i][k], dp[i][j][k] + dis[j][i+1] );//j走到i+1
dp[i+1][i][j] = min( dp[i+1][i][j], dp[i][j][k] + dis[k][i+1] );//k走到i+1
for( int temp = j + 1; temp <= i; temp++ ){//j向前走  temp为走之后的位置
dp[i][temp][k] = min( dp[i][temp][k], dp[i][j][k] + dis[j][temp] );
}
for( int temp = k + 1; temp <= i; temp++ ){//k向前走  temp为走之后的位置
if( temp <= j ){
dp[i][j][temp] = min( dp[i][j][temp], dp[i][j][k] + dis[k][temp] );
}else{
dp[i][temp][j] = min( dp[i][temp][j], dp[i][j][k] + dis[k][temp] );
}
}
}
}
}
int ans = MAX;
for( int i = 1; i <= N; i++ ){
for( int j = 1; j <= i; j++ ){
ans = min( ans, dp
[i][j] );
}
}
cout << ans << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: