//1489蜥蜴和地下室
/*先处理第一个弓箭手和最后一个,
中间的弓箭手x有两种被消灭的方法,
假如打死第x-1个弓箭手后,x没有死。
那么第一种是通过直接被打死,
第二种是通过攻击x+1的弓箭手*/
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 30
#define inf 0x3f3f3f3f
typedef long long ll;
int n,a,b,A[maxn],tmp=inf;
ll ans=0;
void dfs(int x,int num) //x是当前弓箭手的序号,num是当前释放的火焰的数目
{
// tmp=0;
if(x==n-1){
tmp=min(num,tmp);
return ;
}
int t=0;
/*每一次向后搜索都要保证X-1为负数
前面一个还没死,只能通过打后面一个附带杀死x-1*/
if(A[x-1]<0) dfs(x+1,num);
if(A[x-1]>=0){
t=A[x-1]/b+1;
A[x-1]-=t*b;
A[x]-=t*a;
A[x+1]-=b*t;
dfs(x+1,num+t);
A[x-1]+=t*b;
A[x]+=t*a;
A[x+1]+=b*t;
}
//假如打爆x-1后x还活着,那么打x次数一定还要大于t(杀死前面一个)
int time=A[x]/a+1;
if(time>t&&A[x]>=0){
for(int i=t+1;i<=time;i++){
A[x-1]-=i*b;
A[x]-=i*a;
A[x+1]-=i*b;
dfs(x+1,num+i);
A[x-1]+=i*b;
A[x]+=i*a;
A[x+1]+=i*b;
}
}
return ;
}
int main(){
cin>>n>>a>>b;
for(int i=0;i<n;i++) cin>>A[i];
//先处理两端的
int t1=A[0]/b+1; //小于0才可以
A[0]-=t1*b;
A[1]-=t1*a;
A[2]-=t1*b;
ans+=t1;
if(A[n-1]>=0){
int t2=A[n-1]/b+1;
A[n-1]-=t2*b;
A[n-2]-=t2*a;
A[n-3]-=t2*b;
ans+=t2;
}
//处理中间的
dfs(1,0);
if(tmp!=inf){
ans+=tmp;
}
cout<<ans<<endl;
return 0;
}
WA了,用贪心写的,后来想想这种写法并不对,应该是一道深搜题。
//1489蜥蜴和地下室
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 30
typedef long long ll;
int n,a,b;
ll ans=0;
typedef struct Node{
int l,r,value;
}node;
//判断是不是整数
bool isInterger(double x){
if(x==int(x)) return true;
return false;
}
bool cmp(node a,node b){
return a.value>b.value;
}
node A[maxn];
int main(){
cin>>n>>a>>b;
for(int i=0;i<n;i++){
cin>>A[i].value;
if(i!=0&&i!=n-1){
A[i].l=i-1;
A[i].r=i+1;
}
}
//solve
sort(A+1,A+n-2,cmp);
for(int i=1;i<=n-2;i++){
while(A[i].value>=0){
A[i].value-=a;
A[i-1].value-=b;
A[i+1].value-=b;
ans++;
// cout<<"1 "<<ans<<endl;
}
}
//A[0] and A[n-1]
if(n>3){
while(A[0].value>=0){
A[0].value-=b;
ans++;
}
while(A[n-1].value>=0){
A[n-1].value-=b;
ans++;
}
}
else{
int tmp=max(A[0].value,A[1].value);
while(tmp>=0){
tmp-=a;
ans++;
// cout<<"2 "<<ans<<endl;
}
}
//print
cout<<ans<<endl;
return 0;
}