Hdu1455 Sticks

Sticks
给定k根长度任意的小木棍,求能拼出的最短长度x;
考察:DFS+剪枝;
剪枝方案:
1.对于要拼的长度x,如果不是木棍总长的约数,无法拼;
2.最短长度x一定为大于等于给定木棍中的最长长度;
3.如果当前已经拼成了长度为len的木棍,对于一根长为m的木棍如果无法拼成功,那么对于以后的相同长度的木棍也无法拼成;
4.将木棍降序排序,因为长度较长的木棍的可变形较差,也就是说长度较长的木棍一般都是与较短的搭配,而不是较长的与较长的搭配;
5.可能会导致TLE的一点,当拼凑一根新的长度为x的木棍时,如果当前的第一根木棍无法与后面的木棍拼成功的话,那么该方案一定不可行,因为后面也一定无法用上该根木棍的;
Hint:然而没有使用第5点剪枝,能勉强过掉;920ms;

AC记录

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int st[100+10];
int mark[100+10];
int n,cnt,ans,tot,pre,flag;

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

void dfs(int l,int rlen,int num)
{
    if(num==pre)
    {
        flag=1;
        return;
    }
    if(rlen==n) return;
    if(flag)    return;
    for(int i=1;i<=n;i++)
    {
        if(!mark[i])
        {
            if(l+st[i]>cnt) return;
            mark[i]=1;
            if(l+st[i]!=cnt)
                dfs(l+st[i],rlen+1,num);
            else dfs(0,rlen+1,num+1);
            mark[i]=0;
            if(l==0)    continue;//这里本来应使用第5点剪枝的,失败了,望指出错误;
            while(st[i+1]==st[i])   i++;//剪枝3
        }
    }
}


int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)    break;
        memset(st,0,sizeof st);
        tot=cnt=pre=flag=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&st[i]);
            tot+=st[i];
        }
        sort(st+1,st+n+1,cmp);//剪枝4
        for(int i=st[1];i<=tot;i++)//剪枝2
        {   
            if(tot%i==0)//剪枝1;
            {
                memset(mark,0,sizeof mark);
                cnt=i;
                pre=tot/i;
                dfs(0,0,0);
                if(flag==1)
                {
                    printf("%d\n",i);
                    break;
                }
            }
            else continue;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值