大意:先输入一个n,表示有n个炮台的怪物,每次你只能破坏三个炮台,剩下的怪物会攻击中间的英雄,问你把所有怪物消灭完之前,英雄所承受的最小的伤害是多少,注意1-n是一个圈,用状态压缩枚举每一种情况
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 0x3f3f3f3f;
int dp[1<<20];
int sum[1<<20];
int a[110];
int n;
int main()
{
scanf("%d",&n);
for(int i = 0 ; i < n ; i++)
scanf("%d",&a[i]);
for(int i = 0 ; i < (1<<n);i++){
dp[i] = maxn;
for(int j = 0 ; j <n ; j++){
if(i&(1<<j))
sum[i] += a[j];
}
}
dp[(1<<n)-1] = 0;
int t1,t2,x;
for(int i = (1<<n)-1;i >= 0;i--){
for(int j = 0 ; j < n ;j++){
if(i&(1<<j)){
x= i - (1<<j);
if(j-1<0)
t1 = n -1;//找上一个炮台
else t1 = j - 1;
if(j + 1 >= n)
t2 = 0;
else t2 = j + 1;
if(x&(1<<t1))
x -= (1<<t1);
if(x&(1<<t2))
x -= (1<<t2);
dp[x] = min(dp[x],dp[i]+sum[x]);
}
}
}
printf("%d\n",dp[0]);
return 0;
}