HDU1027-Ignatius and the Princess II

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;//对于一个序列排列好之后,则都被访问过,所以为了下一次搜索需要清零 
            }
        }
    }
}

 

转载于:https://www.cnblogs.com/Yvettey-me/p/4520942.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值