zoukankan      html  css  js  c++  java
  • POJ 1011 Sticks

    POJ_1011

    做完这个题目,让我不仅学到了一些别人剪枝的策略,更重要的是让我意识到了在搜索中剪枝的重要性。

    所谓剪枝,其实就是对程序的优化,尽可能地避免程序执行无用的操作。就这个题目而言,程序的优化主要有以下几个方面:

    ①我们在拼木棒之前应该对木棒最长到短进行排序,这样方便我们后面挑选木棒的操作,因为如果前面先拼短木棒的话,很有可能后面任何一根木棒都不能填补剩余的长度,而先拼长木棒就可以在本来有解的情况下避免出现这种问题。

    ②枚举拼好的木棒的长度时,枚举区间应在max(len)sum/2之间,如果在这个区间内还没有找到解,那么最后的解只能是sum

    ③枚举的拼好的木棒的长度必须能够整除所有木棒长度和。

    (为了后续描述方便,我们假定现在使用的dfs函数为int dfs(int rest,int complete,int start),其中rest为拼当前木棒时还缺少的长度,complete为已经拼好的木棒数,start为从哪根木棒开始搜索待拼的木棒。同时用d表示枚举的拼好的木棒的长度,cn表示总共可以拼成的木棒的个数。)

    ④搜索过程中,如果这个时候rest==d,也就是说刚刚开始拼一根新的木棒,假如这时把没有用过的最长的一根木棒拼上去,但最后无解的话,那么便不需要去尝试把后面的木棒拼上去了,因为后面不管第几次拼,总要用到这根木棒的,所以出现这种情况,不管后面再尝试拼哪根,最后都一定是无解的。

    ⑤搜索过程中,如果当前木棒和前一根木棒是一样的长度,而前一根木棒没有用过的话,那么这根木棒也一定不使用的,所以直接跳过这根木棒就可以了。

    ⑥搜索过程中,如果遇到一根木棒,它的长度恰好等于rest,但把它拼上去之后无解,那么也便不需要再尝试把后面的木棒拼上去了。

    剪枝确实是门艺术啊,只有勤于思考,善于发现才能把剪枝做好,以后遇到这样的题我一定要更多地独立思考,这样才能更好得锻炼自己的思维能力!

    #include<stdio.h>
    #include
    <string.h>
    #include
    <stdlib.h>
    int state[70],st[70],n,sum,d,cn,min,max;
    int cmp(const void *_p,const void *_q)
    {
    int *p=(int *)_p;
    int *q=(int *)_q;
    return *q-*p;
    }
    int dfs(int rest,int complete,int start)
    {
    int i;
    if(rest==0)
    {
    complete
    ++;
    if(complete==cn)
    return 1;
    for(i=0;st[i]!=0;i++);
    st[i]
    =1;
    if(dfs(d-state[i],complete,i+1))
    return 1;
    st[i]
    =0;
    }
    else
    {
    for(i=start;i<n;i++)
    {
    if(i>0&&state[i]==state[i-1]&&!st[i-1])
    continue;
    if(!st[i]&&rest>=state[i])
    {
    st[i]
    =1;
    if(dfs(rest-state[i],complete,i+1))
    return 1;
    st[i]
    =0;
    if(state[i]==rest)
    break;
    }
    }
    }
    return 0;
    }
    int main()
    {
    int i,j,k,ok;
    while(1)
    {
    scanf(
    "%d",&n);
    if(n==0)
    break;
    sum
    =0;
    for(i=0;i<n;i++)
    {
    scanf(
    "%d",&k);
    sum
    +=k;
    state[i]
    =k;
    }
    qsort(state,n,
    sizeof(state[0]),cmp);
    memset(st,
    0,sizeof(st));
    ok
    =0;
    for(d=state[0];d<=sum/2;d++)
    if(sum%d==0)
    {
    cn
    =sum/d;
    if(dfs(d,0,0))
    {
    ok
    =1;
    printf(
    "%d\n",d);
    break;
    }
    }
    if(!ok)
    printf(
    "%d\n",sum);
    }
    return 0;
    }

      

  • 相关阅读:
    MVC.Net:Razor指定模板
    Intellij Idea 13:导入openfire源代码
    SharePoint 2013:解决爬网出错的问题
    MySQL:解决MySQL无法启动的问题
    SharePoint 2013:解决添加域名后每次都需要登录的问题
    Android 动画
    android:persistent属性
    ubuntu 安装 open in teminal
    利用python建表
    flask request
  • 原文地址:https://www.cnblogs.com/staginner/p/2143614.html
Copyright © 2011-2022 走看看