思路
- 题意:杀死n个敌人,你的火球可以给某个位置的敌人造成a点伤害,并且给该位置的相邻位置造成b点溅射伤害,并且你不能直接发火球攻击第一个和最后一个敌人,求最少需要多少次火球
- 做法:dfs,不过这里有一个顺序,是一个顺序dfs,从左往右开始dfs,每一次枚举一下对i位置发射多少次火球,必须要保证i-1位置的敌人已经被消灭,因为我们是顺序枚举,所以如果在枚举i的时候不把i-1位置的敌人消灭,之后没法消灭了。
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define MAXN 20
int h[MAXN],n,a,b,ansn=10000000;
vector<int> tmp;
vector<int> ans;
void dfs(int i,int sum)
{
if(sum>=ansn) return ;
if(i==n)
{
if(h[i]<0&&sum<ansn)
{
ansn=sum;
ans=tmp;
}
return ;
}
for(int j=0;j<=max(h[i-1]/b+1,max(h[i]/a+1,h[i+1]/b+1));j++)
{
if(h[i-1]<b*j)
{
h[i-1]-=b*j;
h[i+1]-=b*j;
h[i]-=a*j;
for(int k=1;k<=j;k++)
tmp.push_back(i);
dfs(i+1,sum+j);
h[i-1]+=b*j;
h[i+1]+=b*j;
h[i]+=a*j;
for(int k=1;k<=j;k++)
tmp.pop_back();
}
}
}
int main()
{
scanf("%d %d %d",&n,&a,&b);
for(int i=1;i<=n;i++)
scanf("%d",&h[i]);
dfs(2,0);
printf("%d\n",ansn);
for(int i=0;i<ans.size();i++)
printf("%d ",ans[i]);
return 0;
}