zoukankan      html  css  js  c++  java
  • POJ 1011 Sticks​ (DFS + 剪枝)

    题目地址:http://poj.org/problem?id=1011

    题目大意

    给出n个小木棒,组合成若干长度最短棍子

    解题思路

    • 首先将木棒从大到小排序
    • dfs(k, l), k是还剩多少木棒没用,l是当前没组装成功的棍子还需多长木棒
    • 剪枝(核心)
      • 选取能被木棒总长度能整除的棍子长度
      • 如果当前选取木棒的长度比所需的长度大,剪枝
      • 如果剩余的木棒总长度还没所需的长度大,剪枝
      • dfs每一次开始选取木棒,要从上一次选取的后面开始
      • 对于相等的木棒,如果一次不成功,就无需再次尝试

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int a[100], v[100], n, len, cnt;
    
    // 正在拼第stick根原始木棒(已经拼好了stick-1根)
    // 第stick根木棒的当前长度为cab
    // 拼接到第stick根木棒中的上一根小木棍为last
    bool dfs(int stick, int cab, int last) {
    	// 所有原始木棒已经全部拼好,搜索成功
    	if (stick > cnt) return true;
    	// 第stick根木棒已经拼好,去拼下一根
    	if (cab == len) return dfs(stick + 1, 0, 1);
    	int fail = 0;
    	// 小木棍长度递减(从last开始枚举)
    	for (int i = last; i <= n; i++)
    		if (!v[i] && cab + a[i] <= len && fail != a[i]) {
    			v[i] = 1;
    			if (dfs(stick, cab + a[i], i + 1)) return true;
    			fail = a[i];
    			v[i] = 0; // 还原现场
    			if (cab == 0 || cab + a[i] == len) return false; 
    		}
    	return false; // 所有分支均尝试过,搜索失败
    }
    
    int main() {
    	while (cin >> n && n) {
    		int sum = 0, val = 0, m = 0;
    		for (int i = 1; i <= n; i++) {
    			int x;
    			scanf("%d", &x);
    			if (x <= 50) {
    				a[++m] = x;
    				sum += a[m];
    				val = max(val, a[m]);
    			}
    		}
    		n = m;
    		sort(a + 1, a + n + 1);
    		reverse(a + 1, a + n + 1); 
    		for (len = val; len <= sum; len++) {
    			if (sum % len) continue;
    			cnt = sum / len; // 原始木棒长度为len,共cnt根
    			memset(v, 0, sizeof(v));
    			if (dfs(1, 0, 1)) break;
    		}
    		cout << len << endl;
    	}
    }
    
  • 相关阅读:
    Python之路——内置函数
    Python之路——迭代器与生成器
    Python之路——函数
    Python之路——琐碎知识
    oracle 11g ocp 笔记(17)--rman高级功能
    oracle 11g ocp 笔记(16)--使用rman进行恢复
    oracle 11g ocp 笔记(15)--使用rman进行备份
    oracle 11g ocp 笔记(14)--数据库备份和恢复配置
    oracle 11g ocp 笔记(13)--子查询和集合运算符
    oracle 11g ocp 笔记(12)--sql关联
  • 原文地址:https://www.cnblogs.com/RioTian/p/13470232.html
Copyright © 2011-2022 走看看