深搜剪枝

来源:互联网 发布:字幕软件哪个好 编辑:程序博客网 时间:2024/05/17 23:35
#include<bits/stdc++.h>//思路暴力枚举每个位置放的个数using namespace std;int c[12];int p[12];int n,a,b;int Ans;int ans[12];//保存结果用int s1,s2;void dfs(int pos,int num){    if(num>=Ans) return;//普遍剪枝    if(pos==n)    {        int i;        for(i=1;i<=n;i++) if(c[i]>=0) {break;}        if(i>n){Ans=num;}        return;    }    int st=0;    if(pos==2)//按题目要求剪枝,没2-n范围的要求要tl    {        int s=0,num=0;        while(1)        {            s=s+b;            num++;            if(s>s1) break;        }        st=num;    }    else if(pos==n-1)    {         int s=0,num=0;         while(1)         {             s=s+b;             num++;             if(s>s2) break;         }         st=num;    }    for(int i=st;i<=p[pos];i++)    {        if(i==0) {ans[pos]=0;dfs(pos+1,num);}//debug        else        {            if(c[pos-1]<0&&c[pos]<0&&c[pos+1]<0) continue;            int tmp1=c[pos-1],tmp2=c[pos],tmp3=c[pos+1];//回溯易出bug            c[pos-1]=c[pos-1]-i*b;            //pos-debug            c[pos]=c[pos]-i*a;            c[pos+1]=c[pos+1]-i*b;            ans[pos]=i;            dfs(pos+1,num+i);            c[pos-1]=tmp1;            c[pos]=tmp2;            c[pos+1]=tmp3;        }    }}int main(){    while(scanf("%d%d%d",&n,&a,&b)!=EOF)    {        for(int i=1;i<=n;i++) {scanf("%d",&c[i]);}        s1=c[1],s2=c[n];        for(int i=2;i<=n-1;i++) //预处理每个位置放的个数的最大值        {            int j;            for(j=1;;j++)            {                if(b*j>c[i-1]&&a*j>c[i]&&b*j>c[i+1]) break;            }            p[i]=j;        }        Ans=999999999;        dfs(2,0);        cout<<Ans<<endl;    }    return 0;}