uva 11491 Erasing and Winning 奖品的价值 (单调队列)
2016-04-13 08:28
507 查看
解题关键在于,首先要发现性质,题目要求在n个有序数字中,选取n-d个数字,使得剩下组成的数最大。
先考虑选取第一位:越大越好,越靠左越好。
解法:维护一个单调递减的队列。
先考虑选取第一位:越大越好,越靠左越好。
解法:维护一个单调递减的队列。
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> #include<vector> using namespace std; #define all(x) (x).begin(), (x).end() #define for0(a, n) for (int (a) = 0; (a) < (n); (a)++) #define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++) typedef long long ll; typedef pair<int, int> pii; const int INF =0x3f3f3f3f; const int maxn= 100000 ; int n,d,V; char s[maxn+10]; bool vis[maxn+10]; int q[maxn+10]; int main() { while(~scanf("%d%d",&n,&d)&&(n||d)) { scanf("%s",s+1); V=n-d; memset(vis,0,(n+1)*sizeof vis[0]); int rear=1,front=1; for(int i=1;i<=n-V;i++ ) { while(rear-front>0&&s[q[rear-1]]<s[i] ) rear--; q[rear++]=i; } for(int i=n-V+1;i<=n;i++) { while(rear-front>0&&s[q[rear-1]]<s[i] ) rear--; q[rear++]=i; int x=q[front]; vis[x]=1; front++; } for(int i=1;i<=n;i++) if(vis[i]) { putchar(s[i]); } putchar('\n'); } return 0; }
相关文章推荐
- 设计模式——工厂模式和策略模式的区别
- strcmp()函数自实现
- HTTP协议详解
- android基础---->DiskLruCache的使用及原理
- js typeof
- 跨线程实时更新进度类
- Android手机上生成随机验证码(详细注释)
- Tricks(三十四)—— 判断某一属性列是数值型还是标称型
- ocr识别
- Ubuntu 14.04下NFS安装配置
- curl进行传值(post)
- java集合框架02——Collection架构与源码分析
- POJ2502 Subway(最短路径)
- dp基础习题(4.13)
- 网络:登录界面搭建与数据保存
- LeetCode 143. Reorder List
- 采集(file_get_contents)
- Android OCR 之 tesseract
- WKWebView中HTML5获取位置失败
- Android studio 中使用xUtils报错找不到org.apache.http.client.methods.HttpRequestBase的类文件