hdu1051 Wooden Sticks(DP入门)
2016-02-06 11:54
435 查看
题目大意:
给n根木棍的长度和重量。根据要求求出制作木棍的最短时间。建立第一个木棍需要1分钟,若是接着要制作的木棍重量和长度都比此木棍长就不需要建立的时间,若是没有,则再需要建立时间。求时间最小为多少。
传说中的动态规划第一题。。。光看英语题就看了好久。。。
本题刚开始一看,这尼玛真简单,排个序筛选就行了,然而还是我图样。。。
拿第一个样例来说,排好序(1, 4),(2,1),(3,5),(4,9),(5,2)。而最后最好的方案是(5,2)、(2,1);(4,9)、(3,5)、(1, 4)两种。换句话说,排好序后并不是按照顺序筛选,而是无规律的可以跳着筛选,从而找出方案。
这就要求运用动态规划思想,所处理的数组是动态的而不是静态的,时刻在更新,这可能就是DP的核心。
本题关键是这一段代码:
首先按照长度优先降序排序。
1、运用二分查找返回该元素在数组中的下标值,lower_bound是返回大于等于该元素指针(upper_bound是返回大于该元素指针,不能靠字面意思猜测= =);
2、ans的值为动态数组g中有效元素的个数(初始为INF);
3、通过刷新缩小有效元素的值。
下面演示:
1、处理(5,2),k = 1,ans = 1,g[0] = 2;
2、处理(4,9),k = 2,ans = 2,g[0] = 2,g[1] = 9;
3、处理(3,5),k = 2,ans = 2,g[0] = 2,g[1] = 5;
4、处理(2,1),k = 1,ans = 2,g[0] = 1,g[1] = 5;
5、处理(1,4),k = 2,ans = 2,g[0] = 1,g[1] = 4。
也就是说,有效数组只存储一些阈值(有效值),而其余无效值来更新这些值从而缩小范围。所谓的有效,就是以一级排序优先,二级排序基本有序,这才能算有效。
此外排序函数自己写也是计算机的一个优势,真的好神奇哦~
AC代码:
给n根木棍的长度和重量。根据要求求出制作木棍的最短时间。建立第一个木棍需要1分钟,若是接着要制作的木棍重量和长度都比此木棍长就不需要建立的时间,若是没有,则再需要建立时间。求时间最小为多少。
传说中的动态规划第一题。。。光看英语题就看了好久。。。
本题刚开始一看,这尼玛真简单,排个序筛选就行了,然而还是我图样。。。
拿第一个样例来说,排好序(1, 4),(2,1),(3,5),(4,9),(5,2)。而最后最好的方案是(5,2)、(2,1);(4,9)、(3,5)、(1, 4)两种。换句话说,排好序后并不是按照顺序筛选,而是无规律的可以跳着筛选,从而找出方案。
这就要求运用动态规划思想,所处理的数组是动态的而不是静态的,时刻在更新,这可能就是DP的核心。
本题关键是这一段代码:
for(i = 1; i <= n; i ++) { k = lower_bound(g + 1, g + n + 1, sti[i].wei) - g;//1 ans = max(ans, k);//2 g[k] = sti[i].wei;//3 }
首先按照长度优先降序排序。
1、运用二分查找返回该元素在数组中的下标值,lower_bound是返回大于等于该元素指针(upper_bound是返回大于该元素指针,不能靠字面意思猜测= =);
2、ans的值为动态数组g中有效元素的个数(初始为INF);
3、通过刷新缩小有效元素的值。
下面演示:
1、处理(5,2),k = 1,ans = 1,g[0] = 2;
2、处理(4,9),k = 2,ans = 2,g[0] = 2,g[1] = 9;
3、处理(3,5),k = 2,ans = 2,g[0] = 2,g[1] = 5;
4、处理(2,1),k = 1,ans = 2,g[0] = 1,g[1] = 5;
5、处理(1,4),k = 2,ans = 2,g[0] = 1,g[1] = 4。
也就是说,有效数组只存储一些阈值(有效值),而其余无效值来更新这些值从而缩小范围。所谓的有效,就是以一级排序优先,二级排序基本有序,这才能算有效。
此外排序函数自己写也是计算机的一个优势,真的好神奇哦~
AC代码:
#include <stdio.h> #include <string.h> #include <cstdio> #include <algorithm> using namespace std; const int N = 5005; const int INF = 1<<27; struct STI { int len; int wei; }sti ; bool cmp(STI a, STI b) { if(a.len != b.len) return a.len > b.len; else return a.wei > b.wei; } int main() { // freopen("in.txt", "r", stdin); int T, n, i, k, weight, ans; int g ; scanf("%d", &T); while(T --) { scanf("%d", &n); for(int i = 1; i <= n; i ++) { scanf("%d%d", &sti[i].len, &sti[i].wei); g[i] = INF; } // memset(g, INF, sizeof(g)); sort(sti + 1, sti + n + 1, cmp); ans = 0; for(i = 1; i <= n; i ++) { k = lower_bound(g + 1, g + n + 1, sti[i].wei) - g; ans = max(ans, k); g[k] = sti[i].wei; } printf("%d\n", ans); } return 0; }
相关文章推荐
- HDU 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 5592 ZYB's Premutation 线段树(查找动态区间第K大)
- HDU 5240 Exam (好水的题)
- HDU5237 Base64 大模拟
- HDU 1000
- HDU 1001
- 2015-11-11 hdu新生赛 A题(AC)
- 2015-11-11 hdu新生赛 C题(结束后一发AC)
- 2015-11-11 hdu新生赛 E题(结束后一发AC)
- 2015-11-11 hdu新生赛 F题(结束后一发AC)
- hdu-5385