UVA-11491 Erasing and Winning (单调队列)
题目大意:给一个数字(开头非0),拿掉其中的d个数字,使剩下的数字最大(前后顺序不能变)。
题目分析:拿掉d个数字,还剩下n-d个数字。相当于从n个数字中按先后顺序选出n-d个数字使组成的数字最大,当然采用窗口滑动优先选取大的。
代码如下:
# include<iostream> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; struct Num { int val,id; }; Num num[100005],que[100005]; char p[100005]; int vis[100005]; void solve(int k,int l) { int head=0,tail=-1; for(int i=0;i<k-1;++i){ while(head<=tail&&que[tail].val<num[i].val) --tail; ++tail; que[tail]=num[i]; } int id=-1; for(int i=k-1;i<l;++i){ while(head<=tail&&que[tail].val<num[i].val) --tail; ++tail; que[tail]=num[i]; while(que[head].id<i-k+1||que[head].id<=id) ++head; printf("%d",que[head].val); id=que[head].id; } printf("\n"); } int main() { int n,d; while(scanf("%d%d",&n,&d)&&n+d) { scanf("%s",p); int l=strlen(p); for(int i=0;i<l;++i) num[i].val=p[i]-'0',num[i].id=i; solve(d+1,l); } return 0; }