小木棍_洛谷1120_搜索

来源:互联网 发布:mac. wps 编辑:程序博客网 时间:2024/04/28 22:53

题目描述


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

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

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

输入格式:


输入文件共有二行。

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

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

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

输出格式:


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

Analysis


题意读懂了就是把一坨数字分成整数组且每组和相等,求最大组数也就是最小的每组和
传送门
然而这道更恶心,除了dfs还要一堆的优化

  1. 对于无法找到方案的相同长度的木棍都不能选
  2. 构成大木棍的小木棍长度必定是递减的,那么每次记录一个last
  3. 找到了方案就能halt了
    老夫的正确率

Code


#include <stdio.h>#include <string.h>#include <algorithm>#define rep(i, a, b) for (int i = a; i <= b; i++)#define fill(x, t) memset(x, t, sizeof(x))#define INF 0x3f3f3f3f#define N 101using namespace std;bool flag;int t[N], vis[N], l[N], last = 1;inline int read(){    int x = 0, v = 1;    char ch = getchar();    while (ch < '0' || ch > '9'){        if (ch == '-'){            v = -1;        }        ch = getchar();    }    while (ch <= '9' && ch >= '0'){        x = x * 10 + ch - '0';        ch = getchar();    }    return x * v;}inline int max(int x, int y){    return x<y?y:x;}inline int min(int x, int y){    return x<y?x:y;}inline int cmp(int x, int y){    return x>y;}inline int dfs(int dep, int len, int now, int n){    if (flag){        return 0;    }    if (dep == n + 1 && !now){        flag = true;        return 0;    }    if (!now){        now = len;    }    int qq = 1;    if (now != len){        qq = last;    }    rep(i, qq, n){        if (!vis[i] && now >= t[i]){            vis[i] = 1;            last = i + 1;            dfs(dep + 1, len, now - t[i], n);            vis[i] = 0;            if (now == t[i] || now == len || flag){                break;            }            while (t[i] == t[i + 1]){                i ++;            }        }    }    return 0;}int main(void){    int n = read();    int cnt = 0;    rep(i, 1, n){        t[++ cnt] = read();        if (t[cnt] > 50){            cnt --;        }    }    n = cnt;    int tot = 0;    rep(i, 1, n){        tot += t[i];    }    flag = false;    sort (t + 1, t + n + 1, cmp);    rep(i, 1, tot){        if (tot % i == 0){            fill(vis, 0);            dfs(1, i, i, n);            if (flag){                printf("%d\n", i);                return 0;            }        }    }    return 0;}
0 0
原创粉丝点击