题目链接:http://lightoj.com/volume_showproblem.php?problem=1037
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = 1<<16; const int INF = 0x3f3f3f3f; int dp[maxn]; //dp[S]代表杀死集合S中的人需要的最小shot数。 char s[16][16]; int Hel[16]; int N; int main() { //freopen("E:\acm\input.txt","r",stdin); int T; cin>>T; for(int cas=1; cas<=T; cas++) { cin>>N; for(int i=0; i<N; i++) scanf("%d",&Hel[i]); for(int i=0; i<N; i++) scanf("%s",s[i]); memset(dp,0x3f,sizeof(dp)); int All = (1<<N)-1; for(int i=0; i<N; i++) dp[1<<i] = Hel[i]; for(int S=1; S<=All; S++) { for(int i=0; i<N; i++) { if(!(1<<i&S)) continue; for(int j=0; j<N; j++) { if(((1<<j)&S) || i==j) continue; if(s[i][j] == '0') { dp[S|1<<j] = min(dp[S|1<<j],dp[S] + Hel[j]); continue; } int num = s[i][j] - '0'; int add = Hel[j]/num; if(Hel[j]%num>0) add++; dp[S|1<<j] = min(dp[S|1<<j],dp[S] + add); } } } printf("Case %d: %d ",cas,dp[All]); } }