AOJ_2254
bitDPで解けた。
ビットの例…11001001 1,4,7,8のアイテム
#include <cstdio> #include <algorithm> using namespace std; const int INF = 10000000; const int MAX_N = 16; const int MAX_C = 1 << MAX_N; int table[MAX_N + 1][MAX_N + 1];//ステージnをアイテムmでクリアするときにかかる時間 int dp[MAX_C]; int N; /* bitDP i = ビット表現でアイテムの種類 dp[i] := iで表されたアイテムすべてを手に入れるための最短時間 dp[0] := 0 dp[i] := min(dp[i & ~k] + table[kに対応するステージ番号][(j ∈ (i & ~k))に対応するアイテム番号] k,jは,iで立っているビットのうちの,一つのビットだけが立っている */ bool isbit(int b, int p){ //bのp番目のビットがたっているか if(p == 0) return true; return ((b >> (p - 1)) & 1 == 1); } int solve(int n){ dp[0] = 0; for(int i = 1; i < (1 << n); i++){ dp[i] = INF; int k; for(int p = 1; p <= n; p++){ if(isbit(i, p)){ //iのp番目のビットが立っている k = 1 << (p - 1); for(int j = 0; j <= n; j++){ if(isbit((i & ~k), j)){ dp[i] = min(dp[i], dp[i & ~k] + table[p][j]); } } } } } return dp[(1 << n) - 1]; } int main(){ while(scanf("%d", &N)){ if(N == 0) return 0; for(int i = 1; i <= N; i++){ for(int j = 0; j <= N; j++){ scanf("%d", &table[i][j]); } } printf("%d\n", solve(N)); } return 0; }