数位DP + 记忆化搜索。。。。
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX 0x3f3f3f3f
typedef struct{
int p[20];
}Node;
int dp[1<<16];
int power[16][16];
int N;
int blood[20];
int DFS( int statu, Node now ){//statu表示当前杀了哪些人 哪些人没杀 now表示目前射杀每个人所能射杀的最大血量
if( statu == 0 ){
return 0;
}
if( dp[statu] != MAX ){
return dp[statu];
}
for( int i = 0; i < N; i++ ){
if( statu & ( 1 << i ) ){//若i没死 射杀i
Node newnode;
for( int j = 0; j < N; j++ ){
newnode.p[j] = max( now.p[j], power[i][j] );//更新枪的能量
}
dp[statu] = min( dp[statu], DFS( statu ^ ( 1 << i ), newnode ) + ( blood[i] - 1 ) / now.p[i] + 1 );
}
}
return dp[statu];
}
int main(){
int T, Case = 1;
char s[20];
Node now;
cin >> T;
while( T-- ){
cin >> N;
for( int i = 0; i < N; i++ ){
cin >> blood[i];
now.p[i] = 1;//初始化枪的能量为1
}
memset( dp, 0x3f, sizeof( dp ) );
for( int i = 0; i < N; i++ ){
scanf( "%s", s );
for( int j = 0; j < N; j++ ){
power[i][j] = s[j] - '0';
}
}
cout << "Case " << Case++ << ": " << DFS( ( 1 << N ) - 1, now ) << endl;
}
return 0;
}