标签:
http://acm.hdu.edu.cn/showproblem.php?pid=1027
这道题的意思是输出n个数全排列的第m个全排列。
很明显这道题用的是可以用深搜来解决这个问题,
我的思路是:寻找的是最优子结构,当全排列的第一个数确定之后,就第二个数就是n个数出去第一个数字的任意一个可能。
深搜是状态转移,从一个状态转换到另一个状态。
//hdu1027 #include <iostream> #include <cstdio> #include <cstring> //注意为什么要用flag标记提前跳出循环。//回溯的原因!! /** 主要原因: 1.如果直接return的话就只是跳到上一层, 而flag是在回溯之前就定义好的, 所以当用flag标记直接调回的时候就不会仅仅返回第上一层,而是直接 逐层返回到第一层,然后结束。 **/ using namespace std ; int n,m,flag; int a[1002],sum,vis[1002]; void dfs(int k); int main(){ while(~scanf("%d%d",&n,&m)){ memset(vis, 0, sizeof(vis)); sum=flag=0; dfs(1); } return 0; } void dfs(int k){ if(flag==1)return;//提前结束 if(k==n+1){ sum++; if(sum==m){ flag=1; for(int i=1;i<n;i++){ printf("%d ",a[i]); } printf("%d\n",a[n]); return;//返回上一层 } }else{ //这样做会多一个循环,运行超时,最好的办法就是记忆化 // for(int i=1;i<=n;i++){ // int flag=1; // for(int j=1;j<k;j++){ // if(i==a[j]){ // flag=0; // } // } // if(flag==1){ // a[k]=i; // dfs(k+1); // } // } for(int i=1;i<=n;i++){ if(!vis[i]){ vis[i]=1; a[k]=i; dfs(k+1); vis[i]=0;//对于一个序列排列好之后,则都被访问过,所以为了下一次搜索需要清零 } } } }
HDU1027-Ignatius and the Princess II
标签:
原文地址:http://www.cnblogs.com/Yvettey-me/p/4520942.html