CF285D (打表+搜索)
Posted huayucaiji 的博客小屋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF285D (打表+搜索)相关的知识,希望对你有一定的参考价值。
CF285D
解题思路
这个题,我一看,哦,\\(n\\leq 16\\),而且又是输入只有 \\(n\\)。果断打表啊!
关键在于如何快速打表。
我们可以先找出 \\(C=(1,2,\\cdots,n)\\) 的方案数,然后再乘以 \\(n!\\) 就是总方案数了。我们如果爆搜的话就是 \\(O(n*n!)\\)。看起来好像跑的很慢 ,其实加上合理剪枝跑的速度还可以接受。
我们如果手玩一下 \\(n\\leq 5\\) 的结果,或者让程序跑 \\(n\\leq 12\\) 的答案(这部分跑的飞快),你就会发现 \\(n\\) 为偶数的时候,答案是 \\(0\\)。这样我们对于 \\(n\\) 为偶数的情况又可以不算了。
如果你像追求更高的效率,可以使用 Meet-in-the-middle。当然,不加这个优化也可以在 \\(6\\ min\\) 内跑完,最后打表即可。
代码
//Don\'t act like a loser.
//This code is written by huayucaiji
//You can only use the code for studying or finding mistakes
//Or,you\'ll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
using namespace std;
int read() {
char ch=getchar();
int f=1,x=0;
while(ch<\'0\'||ch>\'9\') {
if(ch==\'-\')
f=-1;
ch=getchar();
}
while(ch>=\'0\'&&ch<=\'9\') {
x=x*10+ch-\'0\';
ch=getchar();
}
return f*x;
}
const int MAXN=16,MOD=1e9+7;
int n;
int ans[MAXN],jc[MAXN];
bool vis[MAXN][2];
void dfs(int n,int x) {
if(x==n+1) {
ans[n]++;
return ;
}
for(int i=1;i<=n;i++) {
if(!vis[i][0]) {
int j=(x-1-i+2+n)%n;
if(!j) {
j=n;
}
if(!vis[j][1]) {
vis[i][0]=1;
vis[j][1]=1;
dfs(n,x+1);
vis[i][0]=0;
vis[j][1]=0;
}
}
}
}
int main() {
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
int t=16;
jc[0]=1;
for(int i=1;i<=t;i++) {
jc[i]=1ll*jc[i-1]*i%MOD;
if(i&1) {
dfs(i,1);
ans[i]=1ll*ans[i]*jc[i]%MOD;
}
else {
ans[i]=0;
}
printf("ans[%d]=%d;\\n",i,ans[i]);
}
//fclose(stdin);
//fclose(stdout);
return 0;
}
不会有人直接交这个程序吧。。。。
这个是打表用的(坑一下直接抄题解的人)
以上是关于CF285D (打表+搜索)的主要内容,如果未能解决你的问题,请参考以下文章
codeforces Goodbye2018 C. New Year and the Permutation Concatenation 傻瓜解法找规律+打表
zoj 2723 Semi-Prime(素筛打表+搜索优化)
CF-1362C. Johnny and Another Rating Drop