CF6D Lizards and Basements 2
题意:有n个人,编号1到n,每个人有血量h i h_ihi对某个人攻击会产生a点伤害,会波及到相邻的人,对相邻的人产生b点伤害(1和n号人不能攻击),问最少要攻击多少次才能让所有人的h小于0,分别攻击了谁。
解法:dfs搜索,先处理出每个人最多攻击多少次,对攻击次数枚举,每次保证当前点前所有人h值已经小于0。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 20;
int n, a, b, h[N], ci[N], tmp[N];
int res = 1e9, r[N];
void dfs(int step, int ans) {
if(ans >= res) return ;
// cout << step << endl;
if(step == n) {
// cout << ans << " " << res << " " << h[n] << endl;
if(h[n] < 0) {
if(ans < res) {
for(int i = 2; i <= step; ++i) r[i] = tmp[i];
res = ans;
}
}
return;
}
for(int i = 0; i <= ci[step]; ++i) {
if(i*b <= h[step-1]) continue;
tmp[step] = i;
h[step+1] -= i*b;
h[step] -= i*a;
dfs(step+1, ans+i);
h[step+1] += i*b;
h[step] += i*a;
tmp[step] = 0;
}
}
int main() {
scanf("%d%d%d", &n, &a, &b);
for(int i = 1; i <= n; ++i) scanf("%d", &h[i]);
for(int i = 2; i < n; ++i) {
ci[i] = max(h[i]/a, max(h[i-1]/b, h[i+1]/b)) + 1;
}
dfs(2, 0);
printf("%d\n", res);
for(int i = 2; i < n; ++i)
for(int j = 0; j < r[i]; ++j) printf("%d ", i);
puts("");
return 0;
}
版权声明:本文为qq_43408978原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。