loj 1037(状圧dp)

7243 ワード

タイトルリンク:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25914
考え方:dp[state]は現在の状態で消費する最小のshotsを表す.
loj 1037(状压dp)
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 using namespace std;

 6 #define inf 1<<30

 7 

 8 int n,val[17],dp[1<<17];

 9 char map[17][17];

10 

11 int main()

12 {

13     int _case,t=1;

14     scanf("%d",&_case);

15     while(_case--){

16         scanf("%d",&n);

17         for(int i=0;i<n;i++)scanf("%d",&val[i]);

18         for(int i=0;i<n;i++)scanf("%s",map[i]);

19         fill(dp,dp+(1<<n),inf);

20         for(int i=0;i<n;i++)dp[1<<i]=val[i];

21         for(int state=0;state<(1<<n);state++){

22             if(dp[state]==inf)continue;

23             for(int i=0;i<n;i++)if(state&(1<<i)){

24                 for(int j=0;j<n;j++)if(!(state&(1<<j))){

25                     int cnt=map[i][j]-'0';

26                     if(cnt==0)dp[state|(1<<j)]=min(dp[state|(1<<j)],dp[state]+val[j]);

27                     else {

28                         cnt=val[j]/cnt+(val[j]%cnt!=0);

29                         dp[state|(1<<j)]=min(dp[state|(1<<j)],dp[state]+cnt);

30                     }

31                 }

32             }

33         }

34         printf("Case %d: %d
",t++,dp[(1<<n)-1]); 35 } 36 return 0; 37 }

View Code