Light OJ 1060 nth Permutation (状压DP)
2016-02-04 20:57
387 查看
题意:给出一个n个字符的字符串(n<=20),求其全排列的第k个排列。
解析:先将字符串排序
状态S记录第i位的字符是否有效。
类比全排列的过程。dp[S]记录状态S中的有效字符组成的序列的排列个数。
根据这个就可以确定第k个排列所在的位置。(具体看代码)
解析:先将字符串排序
状态S记录第i位的字符是否有效。
类比全排列的过程。dp[S]记录状态S中的有效字符组成的序列的排列个数。
根据这个就可以确定第k个排列所在的位置。(具体看代码)
: [code]#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> #define th(x) this->x=x using namespace std; typedef long long LL; const int inf = 0x3f3f3f3f; char s[25],ans[25]; int n,top; LL k,dp[1<<20]; LL dfs(int S,LL k){ if(!S) return 1; if(dp[S]!=-1&&k>dp[S]) return dp[S]; int i,j;bool c[26]; LL res = 0; for(i = 0;i < 26;i++) c[i] = false; for(i = 0;i < n;i++){ if((S>>i&1)&&!c[s[i]-'a']){ c[s[i]-'a'] = true; res += dfs(S^(1<<i),k-res); if(res>=k){ ans[top++] = s[i]; break; } } } return dp[S] = res; } int main(){ int i,j,cas,T; scanf("%d",&cas); for(T = 1;T <= cas;T++){ scanf("%s%I64d",s,&k); n = strlen(s); sort(s,s+n); int S,Ed = 1<<n; dp[0] = 1;top = 0; for(S = 1;S < Ed;S++) dp[S] = -1; dfs(Ed-1,k); printf("Case %d: ",T); if(top != n) puts("Impossible"); else{ for(i = top-1;i>=0;i--) putchar(ans[i]); putchar('\n'); } } return 0; }
相关文章推荐
- leetcode:Range Sum Query 2D - Immutable
- 一起talk C栗子吧(第一百二十回:C语言实例--线程属性)
- 收费的QQ群 改变的不只是所谓的在线教育
- [全局最小割] BZOJ 3345
- Android 简单实现ListView指定ITEM滑到到顶停靠
- Codeforces Round #294 (Div. 2)(A)模拟
- HDU-4866-Shooting(函数式线段树)
- Caused by: java.lang.ClassNotFoundException: flex.messaging.io.BeanProxy
- mac 自动配置java版本
- poj2186 Pupular Cow
- mac 自动配置java版本
- 2.4 XML解析与JSON解析与初识NSURLSession
- jQuery实现简单弹出窗口
- 高精度整数 6
- PySide里如何加载图片资源
- jQuery实现简单选项卡
- iOS-NSNotificationCenter的应用
- hdoj5570balls【求期望】
- 闲聊:项目延期,怎么回事?
- bzoj2671 Calc 数论