分析:
1、贪心,对数组进行扫描,如果a[i]>a[i+1]则把a[i]删除,直到删除m个为止;如果扫描一遍后删除的数不够m个,则在把数组末尾的数删除,直到总的删够m个,数组中剩下的数从头到尾即为结果。
2、RMQ算法解决,假设数组的长度为len,要删除的数的个数为m,那么最终数组中将剩下len-m个,因此可以找出数组中第一个到第m+1个的最小数作为最终结果的第一位,并假设最小数下标为i,再找出第i+1个到第m+2个的最小数作为最终结果的第二位,下标为j,再从第j+1个到m+3个找第三个,以此类推,找完即可。
#include<iostream> using namespace std; int dp[1010][33]; char num[1010]; char res[1010]; void GetRMQ(int n) //注意dp数组中保存的是下标 { int i,j; for(i=0;i<=n;i++) dp[i][0]=i; for(j=1;(1<<j)<=n;j++) for(i=0;i+(1<<j)-1<n;i++) dp[i][j]=num[dp[i][j-1]]<=num[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]; } int Query(int l,int r) { int k=0; while(1<<(k+1)<=r-l+1) k++; return num[dp[l][k]]<=num[dp[r-(1<<k)+1][k]]?dp[l][k]:dp[r-(1<<k)+1][k]; } int main() { int m,pos,k,i; while(scanf("%s %d",num,&m)==2) { pos=0; k=0; i=0; GetRMQ(strlen(num)); while(m+i<strlen(num)) { pos=Query(pos,m+i); res[k++]=num[pos++]; i++; } for(i=0;i<k;i++) if(res[i]!='0') break; if(i==k) putchar('0'); else { for(;i<k;i++) putchar(res[i]); } putchar('\n'); } return 0; }
HDU ACM 3183 A Magic Lamp->RMQ的ST算法或贪心
原文地址:http://blog.csdn.net/a809146548/article/details/45479553