Alien的排列

Alien的排列


  • Description

Alien的思想真的很诡异。
对于一个1…N的排列,Alien们会把它们全部+1,变成2…N+1的Alien排列,然后考虑这个排序的优美程度。
我们称Alien排列的第i个数为Ai,一个排列是优美的当且仅当对于i=1…N,i可以整除Ai。
现在Alien给出一个N,请你求一下N长度的优美排列个数。

  • Input Format

一行一个数N,表示长度为N。

  • Output Format

一行一个数Ret,表示优美排列个数。

  • Sample Input

5

  • Sample Output

3

  • Hint

Data Limitation
对于30%数据:N≤10;
对于100%数据:N≤3000。


  • 分析

对于一个越大的i,可供选择的数也就越少。所以我们从大到小搜索每个位置填的数。(我担心会爆栈所以打了非递归的深搜。)


#include <queue>
#include <stack>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Data{int x,y;};
stack <Data> S;
long long Ans,n,last[3002];
bool P[3002];
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    scanf("%lld",&n);
    for (S.push((Data){n,n});!S.empty();){
        int now=S.top().x;
        P[last[now]]=0; last[now]=S.top().y; P[last[now]]=1; S.pop();
        P[last[now-1]]=0; last[now-1]=0;
        if (now==2){Ans++;continue;}
        for (int i=now-1;i<=n+1;i+=now-1)
            if (!P[i]) S.push((Data){now-1,i});
    }
    printf("%lld",Ans);
    fclose(stdin); fclose(stdout);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值