一道topcoder题目的动态规划解
来源:互联网 发布:淘宝如何加入公益宝贝 编辑:程序博客网 时间:2024/05/17 20:14
文章末尾为问题描述。
看到这道题的时候时间已经不多了,没多想,先对输入的segments排序,直接生成所有可能情况的组合,然后判断每个组合是否满足凸多边形的约束。结束以后分析一下,觉得太费时间了,找了个50个元素的segments和k为10的测试用例,运行时间居然要9分多钟,这显然挂了。
想想这个问题应该有更快的方法,突破点应该就是那些限制条件,就像整数背包问题可以用动态规划解一样。这个可以从公式C(n+1,m)=C(n,m)+C(n,m-1)说起(组合数公式,不知道怎么打公式上来),该公式可以理解为,从{1,2,...,n}选择m个的组合有C(n,m)个,这些组合为{v(1),v(2),...,v(C(n,m))},选择m-1个的组合有C(n,m-1)个,为{u(1),u(2),...,u(C(n,m-1))}。那么现在要求从{1,2,...,n,n+1}中选m个的所有组合,其实可以从前两个来构造,结果就是{v(1),v(2),...,v(C(n,m)), <u(1),n+1>,<u(2),n+1>,...,<u(C(n,m-1)),n+1>},这样就构造出从n+1个元素选m个的C(n+1,m)规模的所有组合来了。
再回到这道题,每个元素的范围是1到50000,最多有50个元素,并且最大的k值是10,那么选出的k个元素的最大和值就是50000*10,并且一定是整数,再根据上一段的分析,我们心里应该已经隐约有个想法了。定义一个二维数组selNums[i][j](i=1,2,...,k; j=1,2,...,50000*10),表示从n个数里选i个的和为j的组的个数,n从2开始逐渐增加到segments.size(),增加的过程中修改二维数组selNums的数据,修改的代码为selNums[ki][ mi+segments[i] ] += selNums[ki-1][mi],这条语句的意思可以从上一段的分析中得出。这样就可得到如下代码。
但是测试后却发现,最大规模数据的运行时间还要4秒多,这不可以。经过分析可以得知,数组selNums的第二维不用弄那么大(我贴的代码中比分析中的值还要大)。我们最终需要的结果是能构成合法凸多边形的个数,所以n个数选m个(m小于k时)的和大于50000的时候,以后再加进来的边都可构成合法凸多边形(因为数据已经排过序,所以后加进来的肯定比以前加进来的大),那么就可以用selNums[i][50001]表示n条边选择i条的和大于5000的组数,这样就得到如下更快的代码。其实做点小修小补也许还能再快点。
可以到地址http://www.topcoder.com/stat?c=problem_solution&rm=301667&rd=13751&pm=9995&cr=22721553看看牛人写的代码以及系统测试数据,那代码我是没怎么看懂,另外要有账号才能看。
Problem Statement
You are given N line segments numbered 1 to N. The lengths of these segments are given in the vector <int> segments. Compose a convex K-sided polygon, where each side is one of the given segments. Each segment can only be used once in the polygon. Return the number of different polygons you can compose. Two polygons are considered different if there exists a segment i such that one of the polygons contains segment i but the other polygon does not.
Definition
Class: Polygons2
Method: number
Parameters: vector <int>, int
Returns: long long
Method signature: long long number(vector <int> segments, int K)
(be sure your method is public)
Notes
A convex polygon can be constructed from a set of segments if the length of each segment from this set is strictly less than the sum of lengths of the remaining segments.
Constraints
segments will contain between 1 and 50 elements, inclusive.
K will be between 3 and 10, inclusive.
Each element of segments will be between 1 and 50,000, inclusive.
Examples
0)
{1,1,1,1}
3
Returns: 4
A nondegenerate triangle can be built using any triple from the given segments.
1)
{2,3,4,5}
3
Returns: 3
Any triple except {2,3,5} will do.
2)
{4,4,4,2,2,2}
3
Returns: 11
You can a make nondegenerate triangle using three segments of length 2, or three segments of length 4, or any two segments of length 4 with any segment of length 2.
3)
{10,1,4,9,20}
4
Returns: 2
One can build a convex quadrangle using segments {10,1,4,9} or {10,4,9,20}.
4)
{3310,1660,211,1260,160,213,884,539,17212,2025,105,120,5510}
7
Returns: 532
- 一道topcoder题目的动态规划解
- 动态规划的一道题目
- 一道动态规划的题目
- 动态规划思想:一道ACM题目
- 一道动态规划 在线coding 题目
- 分享TopCoder的一道题目和个人答案
- Topcoder TriviaGame 动态规划
- 一道动态规划的题
- 一道动态规划的poj
- [topCoder-每日一二题]--[4]----动态规划的使用
- 一道简单的动态规划题
- 关于动态批处理的一道题目
- [topCoder-每日一二题]--[6]----动态规划
- 【动态规划】 TopCoder SRM 555 CuttingBitString
- 【动态规划】TopCoder SRM 573 division2 WolfPackDivTwo
- [acm] 动态规划相关的题目 [ 个人 ]
- 01背包 -- 动态规划的入门题目
- 【转载】一些动态规划的题目
- ORACLE按用户名重建索引
- SQL Server经典论文系列(分门类教程)
- C#.NET去掉gridView1上方的Drag a column header here to group by that column
- 渐变颜色LinearGradientBrush
- DB2
- 一道topcoder题目的动态规划解
- Hibernate配置文件中配置各种数据库的driver、URL
- C#.NET从gridview导出Excel文件
- c#泛形——stack
- 漂亮的按钮
- 整个ADF框架
- 快通应用的log
- 系统文件Hosts的三个特殊妙用
- js 将英文字符串的首字符大写