• 洛谷 P3154 [CQOI2009]循环赛 题解


    u1s1,我的代码在洛谷上只能拿88pts,但在其他OJ上能过,所以如果你想在洛谷上通过这道题那请出门左转。


    这道题看题面和数据范围就知道是搜索加一些神奇的剪枝。

    我一开始的想法是按人枚举,但发现这样连裸的搜索都很难写,所以我转化了一下思路,枚举比赛(即用 ( x , y ) 来表示比赛双方)。

    这样的话裸的搜索就很好写了,分 y = n 和  y != n 两种情况讨论就好了。

    接下来我们来思考几个剪枝:

    1. 如果当前某一方加分后超过最终分数,可以剪枝。

    2. 如果某一方即使后面的比赛全赢也无法到达最终分数,可以剪枝。

    3. 如果当前是某个人的最后一场比赛,可以直接推出结果。

    然后一一实现就好啦~

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define int long long
    #define maxn 10 
    #define rep(i,s,e) for(register int i=s;i<=e;++i)
    #define dwn(i,s,e) for(register int i=s;i>=e;--i)
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
        return f*x;
    }
    inline void write(int x)
    {
        if(x<0){putchar('-');x=-x;}
        if(x>9)write(x/10);
        putchar(x%10+'0');
    }
    int n,ans;
    int s[maxn],f[maxn];
    inline bool check()
    {
        rep(i,1,n)
            if(s[i]!=f[i]) return 0;
        return 1;
    }
    void dfs(int x,int y)
    {
        if(x==n)
            if(check()==1) {++ans; return;}
        if(s[x]+3*(n-y+1)<f[x]) return;//剪枝一
        if(y==n)//剪枝二
        {
            if(f[x]-s[x]==1)
            {
                s[x]++;s[y]++;
                dfs(x+1,x+2);
                s[x]--;s[y]--;
            }
            else if(f[x]-s[x]==0)
            {
                s[y]+=3;
                dfs(x+1,x+2);
                s[y]-=3;
            }
            else if(f[x]-s[x]==3)
            {
                s[x]+=3;
                dfs(x+1,x+2);
                s[x]-=3;
            }
        }
        if(s[x]+3<=f[x])//剪枝三
        {
            s[x]+=3;
            dfs(x,y+1);
            s[x]-=3;
        }
        if(s[y]+3<=f[y])//剪枝三
        {
            s[y]+=3;
            dfs(x,y+1);
            s[y]-=3;
        }
        if(s[x]+1<=f[x]&&s[y]+1<=f[y])//剪枝三
        {
            s[x]++;s[y]++;
            dfs(x,y+1);
            s[x]--;s[y]--;
        }
    }
    signed main()
    {
        n=read();
        rep(i,1,n) f[i]=read();
        dfs(1,2);
        write(ans);
        return 0;
    }
  • 相关阅读:
    [SoapUI] UrlEncode编码/UrlDecode解码网站
    [Token] 从index.jsp中获取Token
    [Groovy]获取当前活动的Environment,获取response中节点的name和节点的value
    [Cookie] Clear Cookie
    [Groovy] Groovy API
    [Schema] I have updated my XML Schema for my service but SoapUI still generates/validates according to the old schema.
    [SoapUI] SoapUI可以做到些什么?功能有多强大?
    [Training Video
    [JSON] Validating/Asserting JSON response with Jsonlurper
    华中农业大学第四届程序设计大赛网络同步赛 I
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/13623886.html
Copyright © 2020-2023  润新知