zoukankan      html  css  js  c++  java
  • uva 307 Sticks

    刚开始在poj过了,拿到uva居然超时。改了好久都没成功,最后问了一个同学,稍微改了一下思路才ac。给uva数据跪了,电费不要钱吗?


    这题数据太恶心,所以必需剪枝。


    1.将数据从大到小排序,方便后面选择和操作。

    2.最后答案只能是sum的约数,所以枚举范围最小为最长的那个棍子的长度,最大只需要到sum/2,如果前面没有求出答案,那么就是sum了。

    3.在深搜过程中,如果当前棍子没有用上,下一个棍子如果长度一样,不用再试。

    4.各种异常情况返回。

    #include "stdio.h"
    #include "string.h"
    #include "algorithm"
    using namespace std;
    
    int a[70],u[70],ans,n,s;
    bool flag;
    
    bool cmp(int x,int y)
    {
        return x>y;
    }
    
    void dfs(int num,int st,int len)
    {
        int i;
        if(num==s) {flag=1;return;}
        if(flag) return;
        for(i=st;i<n;i++)
        {
            if(!u[i])
            {
                u[i]=1;
                if(a[i]+len<ans) dfs(num,i+1,a[i]+len);
                else if(a[i]+len==ans) dfs(num+1,0,0);
                u[i]=0;//恢复现场
                if(!st||a[i]==ans||a[i]+len==ans) return;//4对各种可以继续搜索下去的,却反回了的剪枝。没有这一步会超时
                while(a[i+1]==a[i]) i++;//3中剪枝
            }
        }
        return ;
    }
    
    int main()
    {
        int i,sum;
        while(~scanf("%d",&n))
        {
            if(n==0) break;
            sum=0,flag=0;
            for(i=0; i<n; i++)
            {
                scanf("%d",&a[i]);
                sum+=a[i];
            }
            sort(a,a+n,cmp);//从大到小排序
            for(ans=a[0];ans<=sum/2; ans++)
            {
                if(sum%ans==0)
                {
                    s=sum/ans;
                    memset(u,0,sizeof(u));
                    dfs(0,0,0);
                    if(flag==1) break;
                }
            }
            if(ans>sum/2) printf("%d
    ",sum);
            else printf("%d
    ",ans);
        }
        return 0;
    }


    poj ac代码

    #include "stdio.h"
    #include "string.h"
    #include "algorithm"
    using namespace std;
    
    int a[70],u[70],ans,n;
    
    bool cmp(int x,int y)//sort排序用的
    {
        return x>y;
    }
    
    bool dfs(int num,int len,int st)
    {
        if(num==n) return 1;//全部的棒子都实用了
        else if(len==ans) return dfs(num,0,0);
        else
        {
            int i,t;//t记录ai-1,剪枝,如果相等的棒子第一个没用,后面也不去用
            for(t=0,i=st;i<n;i++)
                if(!u[i]&&len+a[i]<=ans&&t!=a[i])//可以使用
                {
                    t=a[i],u[i]=1;
                    if(dfs(num+1,len+a[i],i+1)) break;
                    u[i]=0;//恢复现场
                    if(st==0) return 0;//如果遍历了一遍后,为找到ai,当前ans错误,返回
                }
                if(n==i) return 0;//如果遍历了一遍后,为找到ai,当前ans错误,返回
                else return 1;
        }
    }
    
    int main()
    {
        int i,sum;
        while(~scanf("%d",&n))
        {
            if(n==0) break;
            sum=0;
            for(i=0; i<n; i++)
            {
                scanf("%d",&a[i]);
                sum+=a[i];
            }
            sort(a,a+n,cmp);//从大到小排序
    
            //从最长的棒子开始遍历,最大为sum
            for(ans=a[0]; ans<sum; ans++)
            {
                if(sum%ans==0)//ans肯定能被sum整除
                {
                    memset(u,0,sizeof(u));//数组清零,0为未用,1为已用
                    if(dfs(0,0,0))
                    break;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }



    版权声明:本文为博主原创文章,未经博主允许不得转载。http://xiang578.top/

  • 相关阅读:
    Effective Java 19 Use interfaces only to define types
    Effective Java 18 Prefer interfaces to abstract classes
    Effective Java 17 Design and document for inheritance or else prohibit it
    Effective Java 16 Favor composition over inheritance
    Effective Java 15 Minimize mutability
    Effective Java 14 In public classes, use accessor methods, not public fields
    Effective Java 13 Minimize the accessibility of classes and members
    Effective Java 12 Consider implementing Comparable
    sencha touch SortableList 的使用
    sencha touch dataview 中添加 button 等复杂布局并添加监听事件
  • 原文地址:https://www.cnblogs.com/xryz/p/4848114.html
Copyright © 2011-2022 走看看