Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7170 Accepted Submission(s): 2866
题意就是
一个序列A[1...N],一共N个数,除去M个数使剩下的数组成的整数最小。就是在A[1...N]中顺次选取N-M个数,使值最小。
直接RMQ,找l到n-m+1的最小值,然后下一个从选取的数下一个开始,因为N-M个数,所以不能过界,要不然长度不够。
不能有前导零,具体的代码里写的。
代码:
1 //HDU 3183.A Magic Lamp-RMQ 2 #include<bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 const int maxn=1e3+10; 6 7 int n,m,h; 8 char c[maxn]; 9 int a[maxn],ans[maxn]; 10 int mi[maxn][maxn]; 11 12 int Min(int x,int y) 13 { 14 return a[x]<=a[y]?x:y; 15 } 16 17 void ST() 18 { 19 for(int i=1;i<=n;i++) 20 mi[i][0]=i; 21 for(int j=1;(1<<j)<=n;j++){ 22 for(int i=1;i+(1<<j-1)<=n;i++){ 23 mi[i][j]=Min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]); 24 } 25 } 26 } 27 28 int query(int l,int r) 29 { 30 int k=0; 31 while((1<<(k+1))<=r-l+1) k++; 32 int cnt=Min(mi[l][k],mi[r-(1<<k)+1][k]); 33 return cnt; 34 } 35 36 int main() 37 { 38 while(~scanf("%s%d",c,&m)){ 39 n=strlen(c);h=0; 40 for(int i=0;i<n;i++) 41 a[i+1]=c[i]-‘0‘; 42 ST(); 43 int l=1; 44 m=n-m; 45 while(m>0){ 46 int pos=query(l,n-m+1); 47 ans[++h]=pos; 48 l=pos+1; 49 m--; 50 } 51 if(h==0) cout<<0<<endl; 52 else{ 53 int flag=0; 54 for(int i=1;i<=h;i++){ 55 if(!flag&&a[ans[i]]==0){ 56 if(i!=h) continue; 57 else cout<<a[ans[i]]; 58 } 59 else{ 60 flag=1;cout<<a[ans[i]]; 61 } 62 } 63 cout<<endl; 64 } 65 } 66 }
HDU 3183.A Magic Lamp-区间找最小值-RMQ(ST)
原文:https://www.cnblogs.com/ZERO-/p/10679789.html