1. 程式人生 > >男神的約會(狀壓dp)

男神的約會(狀壓dp)

alt pri sof cnblogs soft 每次 div src closed

有一天男神約了學姐姐去看電影,電影院有一個活動,給你一個10*10的矩陣,每一個格子上都有一個0-9的整數,表示一共十種優惠券中的一種。

觀眾從左上角的格子開始走,走到右下角。每走到一個有著a號優惠券的格子,都必須要玩一個a分鐘的遊戲來領取這張優惠券。

每次只能向右或向下走。當走到右下角的時候,如果集齊10種優惠券就可以半價看電影呢。

為了能在學姐姐面前展示自己的才智,男神準備用最少的時間領取全部的優惠券(他要省出最多的時間陪學姐姐)。聰明的你能告訴男神,他最少要花費的時間是多少?

Input
輸入包含10行,每行10個數字,以空格隔開,表示格子上的優惠券的種類。數據保證存在合法路徑。

Output


輸出男神走到右下角的最小時間花費。

Sample Input
0 1 2 3 4 5 6 7 8 9
1 1 1 1 1 1 1 1 1 0
2 1 1 1 1 1 1 1 1 0
3 1 1 1 1 1 1 1 1 0
4 1 1 1 1 1 1 1 1 0
5 1 1 1 1 1 1 1 1 0
6 1 1 1 1 1 1 1 1 0
7 1 1 1 1 1 1 1 1 0
8 1 1 1 1 1 1 1 1 0
9 1 1 1 1 1 1 1 1 5
Sample Output
50

//狀態壓縮dp dp[i][j][k] 到(i,j)最少花費的時間

dp[i][j][k] = max ( max ( dp[i][j-1][k] , dp[i][j-1][k&~t] ) , max ( dp[i-1][j][k] , dp[i-1][j][k&~t] ) ) + mp[i][j] ( k = (1<<mp[i][j] ) )

技術分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define INF 0x3f3f3f3f
 5 #define MX 12
 6 
 7 int mp[MX][MX];
 8 int dp[MX][MX][(1<<10)]; // 到 (i,j) 點是 k 狀態最少需要的時間
 9 
10 void solve()
11 {
12     for (int i=1;i<=10;i++)
13         for (int j=1
;j<=10;j++) 14 { 15 if (i==1&&j==1) continue; 16 int t = 1<<mp[i][j]; 17 for (int k=0;k<(1<<10);k++) 18 { 19 dp[i][j][k] = min (dp[i][j][k],dp[i-1][j][k]); 20 dp[i][j][k] = min (dp[i][j][k],dp[i-1][j][k&~t]); 21 dp[i][j][k] = min (dp[i][j][k],dp[i][j-1][k&~t]); 22 dp[i][j][k] = min (dp[i][j][k],dp[i][j-1][k]); 23 dp[i][j][k]+=mp[i][j]; 24 } 25 } 26 } 27 28 void Init() 29 { 30 memset(dp,0x3f,sizeof(dp)); 31 dp[1][1][(1<<mp[1][1])] = mp[1][1]; 32 } 33 34 int main() 35 { 36 for (int i=1;i<=10;i++) 37 for (int j=1;j<=10;j++) 38 scanf("%d",&mp[i][j]); 39 40 Init(); 41 solve(); 42 43 printf("%d\n",dp[10][10][1023]); 44 return 0; 45 }
View Code

男神的約會(狀壓dp)