您的位置:首页 > 其它

bzoj1082: [SCOI2005]栅栏

2016-08-19 11:01 295 查看
二分答案+搜索。

难点是如何不超时。

解决这个问题我用了一些奇技淫巧,当然好多都是借鉴大神们的解法。

 1.if (waste+need>all) return 0;

 2.  if (b[k]==b[k-1])

        {

            if (dfs(k-1,i)) return 1;

        }

最后发现还是超时,然后去掉了几个头文件就过了......

#include<cstdio>

#include<algorithm>

using namespace std;

const int MAXN=1111;

const int MAXM=55;

int a[MAXM],b[MAXN],f[MAXM],allb[MAXM],alla[MAXN];

int n,m,all,l,r,mid,ans,waste,need;

int read()

{

    int f=1,x=0;char ch=getchar();

    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}

    while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}

    return x*f;

}

bool dfs(int k,int start)

{

    if (!k) return 1;

    if (waste+need>all) return 0;

    for (int i=start;i<=m;i++)

    if (f[i]>=b[k])

    {

        f[i]-=b[k];

        if (f[i]<b[1]) waste+=f[i];

        if (b[k]==b[k-1])

        {

            if (dfs(k-1,i)) return 1;

        }

        else if (dfs(k-1,1)) return 1;

        if (f[i]<b[1]) waste-=f[i];

        f[i]+=b[k];

    }

    return 0;

}

bool ok(int p)

{

    waste=0;

    for (int i=1;i<=m;i++) f[i]=a[i];

    need=allb[p];

    return dfs(p,1);

}

void solve()

{

    l=1,r=n,mid,ans;

    while (l<=r)

    {

        mid=(l+r)>>1;

        if (ok(mid)==1) l=mid+1,ans=mid;

        else r=mid-1;

    }

    printf("%d",ans);

}

int main()

{

    m=read();

    for (int i=1;i<=m;i++) a[i]=read();

    n=read();

    for (int i=1;i<=n;i++) b[i]=read();

    sort(a+1,a+m+1);sort(b+1,b+n+1);

    all=0;for (int i=1;i<=m;i++) all=all+a[i];

    allb[0]=0;for (int i=1;i<=n;i++) allb[i]=allb[i-1]+b[i];

    solve();

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: