标签:cto dig memory st算法 desc result nim ota tar
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3964 Accepted Submission(s): 1605
********************************************************************************************************************************************************************************************
题意:给你一个数字串 (每一个串有n个数字), 和一个m (要你删除m个数字 ), 使得剩下的数字组成的整数最小。
一开始想了一下删除m个,等价与在数字串中选择 n-m 个数字组成最小整数。
一开始一直做不出,贪心有点问题。后来被dalao教一下就懂了;
贪心的方法:
我们先假设 n 是串的个数, m 是要删除的个数, need 是需要选的个数;
1) 因为是按照顺序组合数字的, 所以第一个删除的数字一定在 [0, n-need] 之内;
证明: 假设数字有 a0, a1, a2, a3, a4, a5 个,要删除2个,n=6, m=2, need = 4;
因为是连续选择的,我们假设在 [0, 3]之内选择第一个,那么我们只剩下a4, a5了,无法构成4个;
所以假设最后的need-1个我们都要, 那么 从 0 ~ (n - 1) - ( need - 1 )==[0, n-need]之内第一个一定在里面(数组从0开始,所以 n-1);
2) 当在[0, n-need]之内选好了第一个,找到第一个的位置pre,那么下一个 数字一定在 [ pre + 1, n-need + 1 ], 就可以一直找下去了,记录你找到的数;
3) 最后在你找到的数里面讨论前导0的情况。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <vector> 6 #include <deque> 7 using namespace std; 8 const int maxn = 1000+10; 9 int d[maxn][maxn]; 10 int a[maxn]; 11 void RMQ_init(string s) 12 { 13 memset(d, 0, sizeof(d)); 14 memset(a, 0, sizeof(a)); 15 int n = s.size(); 16 for(int i=0;i< n ;i++) a[i]=d[i][0]=s[i]-‘0‘; 17 for(int j = 1; (1<<j) <= n ;j++) 18 for(int i = 0 ; i+(1<<j ) -1 < n ;i++) 19 d[i][j] = min(d[i][j-1] , d[i+(1<<(j-1))][j-1] ); 20 } 21 int RMQ(int L, int R) 22 { 23 int k=0; 24 while((1<<(k+1)) <= R-L+1) k++; 25 return min(d[L][k], d[R-(1<<k) + 1][k]); 26 } 27 int findmin(int L, int R, int Min) 28 { 29 for(int i=L; i <= R ;i++){ 30 if(a[i] == Min) return i; 31 } 32 } 33 int main() 34 { 35 string s; 36 int m, n, need; 37 while(cin >> s >> m){ 38 RMQ_init(s); 39 n = s.size() ; 40 need = n - m; 41 int Left=0, Right = n - need; 42 // cout << Left << " " << Right << endl; 43 // cout << RMQ(Left, Right) << endl; 44 deque <int > q; 45 while(1){ 46 if(need ==0 ) break; 47 int Min = RMQ(Left, Right); 48 // cout << Min << endl; 49 q.push_back(Min); 50 int pre = findmin(Left, Right, Min); 51 Left = pre+1; 52 Right ++ ; 53 need --; 54 } 55 while(!q.empty()){ 56 if(q.front() == 0) q.pop_front(); 57 else break; 58 } 59 if(q.empty()){ 60 cout << "0"; 61 } 62 else{ 63 while(!q.empty()){ 64 cout << q.front(); 65 q.pop_front(); 66 } 67 } 68 cout << endl; 69 } 70 return 0; 71 }
HDU 3183 A Magic Lamp(RMQ问题, ST算法)
标签:cto dig memory st算法 desc result nim ota tar
原文地址:http://www.cnblogs.com/denghaiquan/p/6666168.html