poj1065
来源:互联网 发布:广州恒大淘宝 编辑:程序博客网 时间:2024/06/06 03:18
写了下DP里的poj1065,发现并没有搞懂最好的解法,解法如下(以后在学吧),自己的贪心O(N2)也水过.
题目的确需要稍加思考,这道题的要求其实是将所有stick分为x个不下降子序列( Ai <= Ai+1 ),然后问题归结于求x的最小值。
x的最小值其实等于按l递增排序后stick按w最长下降子序列的长度L,证明如下:
若x < L,先从stick中取出最长下降子序列L,取走的元素留下一个大小相同的“空穴”,然后将剩下的元素和空穴分成x个不下降子序列。接着把最长下降子序列L中的L个元素放回这L个空穴里。由于x < L,所以根据鸽笼原理,必然有两个或两个以上的下降子序列L中的元素(b > a)被按顺序放到同一个不下降子序列(a <= b),产生矛盾(两者本应该是等效的) #include <iostream>
#include <algorithm>#include <vector>#include <iterator>#include <cstring>using namespace std;struct wood{ int l,w; wood () {} wood (int a,int b) : l(a),w(b) {} bool operator < (const wood & a) const { return l == a.l ? w < a.w : l < a.l; }}a[5010];bool vis[5010];int main(){ std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int T; cin >> T; while(T --) { int n; cin >> n; int l,w; for(int i = 0;i < n;i ++) { cin >> a[i].l >> a[i].w; } sort(a,a+n); memset(vis,0,sizeof(vis)); int ans = 0; for(int i = 0;i < n;i ++) { if(!vis[i]) { vis[i] = 1; int now = a[i].w; for(int j = i + 1;j < n;j ++) { if(!vis[j] && a[j].w >= now) { vis[j] = 1; now = a[j].w; } } ans ++; } } cout << ans << endl; } return 0;}
阅读全文
0 0
- poj1065
- poj1065
- poj1065
- poj1065
- poj1065
- poj1065
- poj1065
- poj1065
- poj1065
- Poj1065
- poj1065
- poj1065
- poj1065 贪心
- POJ1065 1548
- poj1065 贪心
- POJ1065+POJ3636
- poj1065贪心
- poj1065 Wooden Sticks
- http请求之HttpURLConnection
- 安卓端车牌识别的研发助力车辆管理
- 使用接口组织枚举
- shellScript之数组操作3
- 一致性哈希算法的原理与实现
- poj1065
- shellScript之数组操作4
- Liunx彩色进度条
- java关于hibernate如何基于注解创建联合主键
- C/C++程序的内存分配
- shellScript之数组操作5
- Django配置Ajax跨域调用/设置Cookie
- Android---广播
- iOS BASE64 编码 和HASH 哈希函数(散列函数) ~用户信息安全