Sticks 

【题目链接】:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=243

【 随 笔 】:很久之前就遇到这道题,题目意思容易理解,后来自己想到了一个法子,思路也很清晰就将代码敲出来了,用了位运算(后来问师兄是说状态压缩,其实我不知道什么是状态压缩~_~),不过提交的时候超时了,我想着优化代码,尽可能加剪枝的条件,却无从下手,后来搜题解搜到了师兄的博客,题解中剪枝的条件自己能想到的五个中了三个,剩下两个剪枝也容易理解,整个DFS的思路也容易理解,这点值得反思,其中的原因我想是自己先入为主了,在之前的思路上瞎折腾,未果却也不接受考虑另外的可能,其实看了师兄的代码思路后,也就是普普通通的暴力回溯,不多说,先保存TL的代码:

【AC的代码链接】:http://www.cppblog.com/y346491470/articles/155318.html

【超时的代码】

 #include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define MAXN 500
using namespace std;
int sticks[MAXN];
bool visit[MAXN];
int n, sumlen, res; bool judge(int fac)
{
int i;
for(i=; i<n && visit[i]; ++i);
if(i<n) return false;
else
{
res = fac;
return true;
}
} bool Traverse(int fac)
{
for(int i=; i<(<<n); ++i)
{
int subsum = ;
bool is_useful = true;
for(int k=; k<n; ++k)
{
if(i&(<<k))
{
if(visit[k] || subsum > fac)
{
is_useful = false;
break;
}
else subsum += sticks[k];
}
}
if(is_useful && subsum == fac)
{
for(int k=; k<n; ++k)
{
if(i&(<<k)) visit[k] = true;
}
if(judge(fac) || Traverse(fac)) return true;
for(int k=; k<n; ++k)
{
if(i&(<<k)) visit[k] = false;
}
}
}
return false;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("F:\\test\\input.txt", "r", stdin);
#endif // ONLINE_JUDGE
while(cin>>n, n)
{
int curmax = ;
sumlen = ;
for(int i=; i<n; ++i)
{
cin>>sticks[i];
curmax = curmax > sticks[i] ? curmax :sticks[i];
sumlen += sticks[i];
}
for(int fac = curmax; fac <= sumlen; ++fac)
{
if(sumlen%fac == )
{
memset(visit, false, sizeof(visit));
if(Traverse(fac))
{
cout<<res<<endl;
break;
}
}
}
} return ;
}

自己后来又重新写了一遍,写的过程中感觉还是对回溯的理解还是不够深,回溯本是暴力的一种,所以这题也能看到一层一层搜索的路径,没有太多的技巧,都是根据题目的特性找规律,充分利用从而写出剪枝的条件,避免了超时,效率也更高。

【AC代码】

 #include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#define MAXN 1000 using namespace std; int sticks[MAXN];
bool visit[MAXN];
int n, length, sum, sumlen; bool cmp(const int& a, const int& b)
{
return a>b;
} bool Traverse(int num, int len, int cur)
{
if(num == sum) return true;
for(int i=cur; i<n; ++i)
{
if(!visit[i] && !(i && !visit[i-] && sticks[i] == sticks[i-]))
{
if(len+sticks[i] == length)
{
visit[i] = true;
if(Traverse(num+, , )) return true;
visit[i] = false;
return false;
}
else if(len+sticks[i] < length)
{
visit[i] = true;
if(Traverse(num, len+sticks[i], i+)) return true;
visit[i] = false;
if(len == ) return false;
}
}
}
return false;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("F:\\test\\input.txt", "r", stdin);
#endif // ONLINE_JUDGE
while(cin>>n, n)
{
int curmax = ;
sumlen = ;
for(int i=; i<n; ++i)
{
cin>>sticks[i];
sumlen += sticks[i];
}
sort(sticks, sticks+n, cmp);
for(int fac = sticks[]; fac <= sumlen; ++fac)
{
if(sumlen%fac == )
{
length = fac;
sum = sumlen/fac;
memset(visit, false, sizeof(visit));
if(Traverse(,,)) break;
}
}
cout<<length<<endl;
} return ;
}

UVa 307 - Sticks的更多相关文章

  1. POJ 1011 / UVA 307 Sticks

    中文题 (一般都比较坑) 思路:DFS (感谢学长的幻灯片) 这破题把我折腾惨了!!!搞了n天 // by Sirius_Ren #include <cstdio> #include &l ...

  2. Sticks(UVA - 307)【DFS+剪枝】

    Sticks(UVA - 307) 题目链接 算法 DFS+剪枝 1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大 ...

  3. 【Uva 307】Sticks

    [Link]: [Description] 给你最多n个棍子; (n< = 64) 每根棍子长度(1..50) 问你这n根棍子,可以是由多少根长度为x的棍子分割出来的; x要求最小 [Solut ...

  4. uva 307

    排序之后再剪枝,有点神 #include <cstdio> #include <cstdlib> #include <cmath> #include <map ...

  5. 紫书 习题7-14 UVa 307(暴搜+剪枝)

    这道题一开始我想的是在排序之后只在头和尾往中间靠近来找木块, 然后就WA, 事实证明这种方法是错误的. 然后参考了别人的博客.发现别人是直接暴搜, 但是加了很多剪枝, 所以不会超时. 我也想过这个做法 ...

  6. hduoj 1455 && uva 243 E - Sticks

    http://acm.hdu.edu.cn/showproblem.php?pid=1455 http://uva.onlinejudge.org/index.php?option=com_onlin ...

  7. UVA题目分类

    题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics ...

  8. uva 10003 Cutting Sticks 【区间dp】

    题目:uva 10003 Cutting Sticks 题意:给出一根长度 l 的木棍,要截断从某些点,然后截断的花费是当前木棍的长度,求总的最小花费? 分析:典型的区间dp,事实上和石子归并是一样的 ...

  9. UVA 10003 Cutting Sticks 区间DP+记忆化搜索

    UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的 ...

随机推荐

  1. windows下python脚本程序的运行

    c:\python33\python.exe c:\python33\trycoding.py

  2. php命令行用法简介

    Php是一个非常流行的web服务端脚本语言.其实,php不仅仅可以在web服务器中充当重要角色.在命令行一样可以执行. 本文中,笔者为各位介绍下php在命令行中的使用方法. 1.  查看php的版本. ...

  3. 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序(老罗学习笔记2)

    在前一篇文章中,我们介绍了如何在Ubuntu上为Android系统编写Linux内核驱动程序.在这个名为hello的Linux内核驱动程序中,创建三个不同的文件节点来供用户空间访问,分别是传统的设备文 ...

  4. 创建支持复杂脚本Complex Scripts的WINCE6.0系统

    如果要创建支持复杂脚本(Complex Scripts)的系统,我们需要完成下面一系列步骤来确保系统包含所有需要支持的具体区域设置 (locale–specific). 1.     选择intern ...

  5. [58 Argo]58同城开源web框架Argo搭建实践

    无意间听说58开源的消息(Long long ago),我辈欣喜异常. 一方面感谢开源同仁的辛苦劳动,另一方面也为我辈在互联网技术实践圈外的人提供了一条实践的渠道. 我迫不及待的从github上dow ...

  6. Building Xcode iOS projects and creating *.ipa file from the command line

    For our development process of iOS applications, we are using Jenkins set up on the Mac Mini Server, ...

  7. EASYUI+MVC4通用权限管理平台

    通用权限案例平台在经过几年的实际项目使用,并取得了不错的用户好评.在平台开发完成后,特抽空总结一下平台知识,请各位在以后的时间里,关注博客的更新. 1.EASYUI+MVC4通用权限管理平台--前言 ...

  8. 设置mysql的interactive_timeout和wait_timeout的值

    1,为什么要重新设置这两个变量的值? 因为如果数据库默认这两个变量的值是8小时(即28800秒)如果在8小时之内没有连接到数据库,等下次再连的时候就会抛连接超时,或连接关闭这样的异 常,但是多连接几次 ...

  9. SyntaxHighlighter -- 代码高亮插件

    SyntaxHighlighter 下载文件里面支持皮肤匹配. 地址:http://alexgorbatchev.com/SyntaxHighlighter/

  10. 解析UML9种图的作用

    本文和大家重点讨论一下UML9种图的概念,UML中有五类图,共有9种图形,每种图形都有各自的特点,下面就让我们一起来看一下这些图形特点的详细介绍吧. UML9种图简介 1.用例图 说明的是谁要使用系统 ...