洛谷P1120 小木棍 [数据加强版]

Posted Soda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1120 小木棍 [数据加强版]相关的知识,希望对你有一定的参考价值。

P1120 小木棍 [数据加强版]

题目描述

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50。

现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

输入输出格式

输入格式:

 

输入文件共有二行。

第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65

(管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!)

第二行为N个用空个隔开的正整数,表示N根小木棍的长度。

 

输出格式:

 

输出文件仅一行,表示要求的原始木棍的最小可能长度

 

输入输出样例

输入样例#1:
9
5 2 1 5 2 1 5 2 1
输出样例#1:
6

说明

2017/08/05

数据时限修改:

-#17 #20 #22 #27 四组数据时限500ms

-#21 #24 #28 #29 #30五组数据时限1000ms

其他时限改为200ms(请放心食用)

技术分享
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 70
using namespace std;
int n,a[maxn],sum,b[3251],cnt,nn;
bool vis[maxn],flag;
void dfs(int now,int num,int limit,int s){//当前和,已经选了多少个木棍,枚举到的答案 
    if(flag)return;
    if(now==0&&(sum-s)%limit)return;
    if(now==0&&num==nn){flag=1;return;}
    for(int i=1;i<=nn;i++){
        if(!vis[i]&&a[i]+now<=limit){
            vis[i]=1;
            if(a[i]+now==limit)dfs(0,num+1,limit,s+a[i]);
            else dfs(now+a[i],num+1,limit,s+a[i]);
            vis[i]=0;
        }
    }
}
int main(){
    freopen("Cola.txt","r",stdin);
    scanf("%d",&n);
    int x;
    for(int i=1;i<=n;i++){
        scanf("%d",&x);
        if(x>50)continue;
        a[++nn]=x;
        sum+=a[nn];
    }
    for(int i=1;i*i<=sum;i++)
        if(sum%i==0){
            b[++cnt]=i;
            if(i*i==sum)break;
            b[++cnt]=sum/i;
        }
    sort(b+1,b+cnt+1);
    for(int i=1;i<=cnt;i++){
        memset(vis,0,sizeof(vis));
        dfs(0,0,b[i],0);
        if(flag){
            printf("%d",b[i]);
            return 0;
        }
    }
}
27分 裸的搜索

 

以上是关于洛谷P1120 小木棍 [数据加强版]的主要内容,如果未能解决你的问题,请参考以下文章

P1120 小木棍 [数据加强版] 题解

P1120 小木棍 [数据加强版]

题解 P1120 小木棍 [数据加强版]

P1120 小木棍 [数据加强版]

洛谷 P1120 小木棍

洛谷P1120 小木棍