现在的位置: 首页 > 综合 > 正文

POJ 1011 Sticks 经典dfs + 剪枝

2018年04月25日 ⁄ 综合 ⁄ 共 1197字 ⁄ 字号 评论关闭

题意:给n(n<=64)根小木棒,每根木棒长度最大为50,问最小能把他们拼成长度为多少的木棒使得小木棒不剩余。

题解:经典dfs+剪枝。总结起来三个剪枝,具体见代码。


Sure原创,转载请注明出处

#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
using namespace std;
const int maxn = 70;
int stick[maxn];
bool vis[maxn];
int sum,n,cur;

bool cmp(const int &a,const int &b)
{
    return a > b;
}

void read()
{
    sum = 0;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&stick[i]);
        sum += stick[i];
    }
    sort(stick , stick + n , cmp);
    return;
}

bool dfs(int st,int cnt,int len)
{
    if(len == cur)   //剪枝1 : 对于当前长度为cur的第一根木棒一定是剩余最大的
    {
        for(int i=0;i<n;i++)
        {
            if(vis[i] == false)
            {
                vis[i] = true;
                if(dfs(i+1,cnt,len-stick[i]) == false)
                {
                    vis[i] = false;
                    return false;
                }
                return true;
            }
        }
        return false;
    }
    if(len == 0)
    {
        if(cnt == 1) return true;
        else return dfs(0,cnt-1,cur);
    }
    for(int i=st;i<n;i++)
    {
        if(vis[i]) continue;
        if(i > 0 && vis[i-1] == false && stick[i] == stick[i-1]) continue;  //剪枝2 : 如果i小木棒和i-1小木棒长度相等且i-1未使用,则跳过i
        if(len >= stick[i])
        {
            vis[i] = true;
            if(dfs(i+1 , cnt , len - stick[i])) return true;
            vis[i] = false;
            if(len == stick[i]) return false;  //剪枝3 : 如果当前最后一根木棒恰好为剩余长度都不能满足,那么直接返回上一层
        }
    }
    return false;
}

void solve()
{
    int res = -1;
    for(int i=stick[0];i<sum;i++)
    {
        if(sum % i == 0)
        {
            memset(vis,false,sizeof(vis));
            cur = i;
            if(dfs(0,sum/i,i))
            {
                res = i;
                break;
            }
        }
    }
    if(res == -1) res = sum;
    printf("%d\n",res);
    return;
}

int main()
{
    while(scanf("%d",&n) && n)
    {
        read();
        solve();
    }
    return 0;
}

抱歉!评论已关闭.