HDU 3183 A Magic Lamp
来源:互联网 发布:淘宝 电脑版 编辑:程序博客网 时间:2024/05/20 21:21
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183
A Magic Lamp
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1763 Accepted Submission(s): 692
The question is: give you an integer, you are allowed to delete exactly m digits. The left digits will form a new integer. You should make it minimum.
You are not allowed to change the order of the digits. Now can you help Kiki to realize her dream?
Each test case will contain an integer you are given (which may at most contains 1000 digits.) and the integer m (if the integer contains n digits, m will not bigger then n). The given integer will not contain leading zero.
If the result contains leading zero, ignore it.
178543 4 1000001 1100001 212345 254321 2
1310123321
[0,m]这个长度为m+1的区间内,也可以用反证法证明,若第一个数在[m+1,n-1]这个区间内,那之后最多能选取n-1-(m+2)+1=n-m-2,事实上我们还差n-m-1个数,所以,原假设不成立。设取出来的第一个数位置为x,则同理,第二个数必然在[x+1,m+1]这个区间里,同样地第三个数在[x',m+2],,,,一直到最后一个数。现在我们要解决的问题是要在[x'+1,m+i](i对应取第i-1个数)这个区间里取一个最小的数,这就是RMQ问题(Range mini query)。可以用线段树实现,不过基于线段树的RMQ创建的复杂度为o(n*log(n))查询复杂度为o(log(n)),而基于稀疏表(ST)的创建复杂度为o(n*log(n)),但查询复杂度为o(1),是一个在线算法。一般如果对区间有更新的话,我们就用线段树,不更新的话用ST算法比较高效。
ST算法是基于动态规划思想实现的。其状态转移方程为dp[i][j]=min(dp[i][j-1],dp[i+(j-1)^2][j-1]),其dp[i][j]代表从i点起长度为2^j的区间的最小(大)值
而查询的话只需要算出能覆盖它的最小区间的最值就可以了。为min(dp[l][((int)log2(len))],dp[r+1-2^((int)log2(len))][(int)log2(len)]);
具体算法设计分析过程可以参考博文http://blog.csdn.net/liang5630/article/details/7917702,此处不再赘述。
AC代码如下
#include<cstdio>#include<cmath>#include<cstring>const int maxn=100005;int dp[maxn][30],m;char s[maxn],ans[maxn];int Min(int i,int j) { return s[i]<=s[j]?i:j;}void InitRMQ(int n){ for(int i=0;i<n;i++) dp[i][0]=i; for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)-1<n;i++) dp[i][j]=Min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);}int RMQ(int l,int r){ int k=(int)(log((r-l+1)*1.0)/log(2.0)); return Min(dp[l][k],dp[r-(1<<k)+1][k]);}int main(){ while(~scanf("%s%d",s,&m)) { int x=0,pa=0,n=strlen(s),pb; InitRMQ(n);//创建ST表 for(int i=0;i<(n-m);i++) x=RMQ(x,m+i),ans[pa++]=s[x++]; for(pb=0,ans[pa]='\0';ans[pb]=='0';pb++); if(pa==pb) printf("0\n"); else printf("%s\n",ans+pb); } return 0;}
- hdu 3183 A Magic Lamp
- hdu 3183 A Magic Lamp
- hdu 3183 A Magic Lamp
- Hdu 3183 A Magic Lamp
- HDU 3183 A Magic Lamp
- HDU 3183 A Magic Lamp
- hdu 3183 A Magic Lamp
- hdu 3183 A Magic Lamp
- HDU 3183 A Magic Lamp
- HDU-3183-A Magic Lamp
- hdu 3183 A Magic Lamp
- HDU-3183-A Magic Lamp
- hdu 3183 A Magic Lamp
- HDU-3183-A Magic Lamp
- HDU 3183 A Magic Lamp
- A Magic Lamp HDU
- A Magic Lamp HDU
- hdu 3183 A Magic Lamp(模拟解法)
- Android Studio问题汇总
- 《数据结构》实验五【顺序树】
- 哈希索引
- C语言中负数怎么表示的?
- node-webkit html5构造可执行程序
- HDU 3183 A Magic Lamp
- 正则表达式
- HDU 1885 BFS+状态压缩
- 排序算法(八)希尔排序(缩小增量排序)
- sql日期处理以及转换
- XML封装通信协议的方法
- 大数据技术收集
- AHK新手入门知识了解
- POJ 2241 The Tower of Babylon(UVA 437)