时间限制:1s

内存限制:256MB

【问题述】

对于一个1~n的排列,如果满足第i个数|ai-i|<=k,则称该排列为K-近似排列。

现在排列的若干位置已经确定,你需要计算剩下的数有多少种排列方法使得形成的排列是K-近似排列。

【输入】

输入文件名为count.in。

第一行一个数T(<=10),表示数据组数

对于每一组数据:

第一行三个数n,m,k,分别表示排列长度、已确定位置的个数和近似参数K

接下来m行,每行两个数x、y,表示已经确定第x个数是y

【输出】

输出文件名为count.out。

对于每组数据输出一行,包含一个数,表示方法个数(对1,000,000,007取模)

【输入输出样例】

count.in

count.out

1

4 1 1

2 3

1

【数据说明】

对于30%的数据,1<=n,m<=10,k<=2

对于50%的数据,1<=n,m<=20,k<=2

对于70%的数据,1<=n<=100000,m<=100,k<=2

对于100%的数据,1<=n<=10^9,m<=100,k<=2

坑啊,题目给的样例不对,他写的是2,其实是1.!

小暴力50分

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,k,t;
int a[];
bool vis[];
long long ans;
void dfs(int x)
{
if(x==n+)
{
ans++;
return ;
}
if(a[x]) dfs(x+);
else
{
if(x>=)
if(!vis[x-k])
{
vis[x-k]=;
dfs(x+);
vis[x-k]=;
return ;
} for(int i=max(x-k,);i<=min(x+k,n);i++)
if(!vis[i])
{
vis[i]=;
dfs(x+);
vis[i]=;
}
}
return ;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++) a[i]=,vis[i]=;
ans=;
for(int i=,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
a[x]=y;vis[y]=;
}
dfs();
printf("%lld\n",ans);
}
return ;
}

50分暴力

也可以用状压dp做

  定义f[j]为当前位上状态为j的方案数,j是一个二进制数,对一每一位上1代表这个数用过,0代表没用过。(其实能用二维的,习惯用一维,有个二维代码)

  对于每个状态,看看能否和    i-k到i+k中每个数拓展,,能拓展的话,就向更大的数扩展。(就是说看看这些数选没选,没选过的话就加过去)。

  

70分还是没写出来。。。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int P=;
int f[<<],a[];
int t,n,m,k;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
memset(a,-,sizeof(a));
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
x--,y--;
a[x]=y;
}
memset(f,,sizeof(f));
for(int i=;i<=k&&i<n;i++)
{
if(a[]!=-&&a[]!=i) continue;
f[<<i]=;
} for(int i=;i<n-;i++)
for(int j=(<<n)-;j>=;j--)
{
if(!f[j]) continue;
for(int t=max(,i+-k);t<=min(n-,i++k);t++)
{
if(j>>t&) continue;
if(a[i+]!=-&&a[i+]!=t) continue;
f[j|(<<t)]=(f[j|(<<t)]+f[j])%P;
}
}
printf("%d\n",f[(<<n)-]); }
return ;
}

50分状压dp-一维

50分DP

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int P=;
int f[][<<],a[];
int t,n,m,k;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
memset(a,-,sizeof(a));
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
x--,y--;
a[x]=y;
}
memset(f,,sizeof(f));
for(int i=;i<=k&&i<n;i++)
{
if(a[]!=-&&a[]!=i) continue;
f[][<<i]=;
} for(int i=;i<n-;i++)
for(int j=;j<(<<n);j++)
{
if(!f[i][j]) continue;
for(int t=max(,i+-k);t<=min(n-,i++k);t++)
{
if(j>>t&) continue;
if(a[i+]!=-&&a[i+]!=t) continue;
if(abs(t-(i+))>k) continue;
f[i+][j|(<<t)]=(f[i+][j|(<<t)]+f[i][j])%P;
}
} printf("%d\n",f[n-][(<<n)-]); }
return ;
}

二维

P4876 近似排列计数50的更多相关文章

  1. BZOJ 4517: [Sdoi2016]排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 911  Solved: 566[Submit][Status ...

  2. bzoj-4517 4517: [Sdoi2016]排列计数(组合数学)

    题目链接: 4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 846  Solved: 530[Submit][ ...

  3. 数学(错排):BZOJ 4517: [Sdoi2016]排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 693  Solved: 434[Submit][Status ...

  4. 【数论·错位排列】bzoj4517 排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1428  Solved: 872[Submit][Statu ...

  5. bzoj4517排列计数 错排+组合

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1491  Solved: 903[Submit][Statu ...

  6. BZOJ_4517_[Sdoi2016]排列计数_组合数学

    BZOJ_4517_[Sdoi2016]排列计数_组合数学 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[ ...

  7. BZOJ 4517--[Sdoi2016]排列计数(乘法逆元)

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1727  Solved: 1067 Description ...

  8. 洛谷P4071 [SDOI2016] 排列计数 [组合数学]

    题目传送门 排列计数 题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m ...

  9. [BZOJ4517][SDOI2016]排列计数(错位排列)

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1616  Solved: 985[Submit][Statu ...

随机推荐

  1. div靠右浮动案例

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  2. bzoj1177&p3625 [APIO2009]采油区域p[大力讨论]

    我好菜菜啊. 给定矩形,从中选出三个边长K的正方形互不重叠,使得覆盖到的数总和最大. 想的时候往dp上钻去了..结果一开始想了一个错的dp,像这样 /************************* ...

  3. tyvj1061移动服务——DP

    题目:http://www.joyoi.cn/problem/tyvj-1061 DP记录状态为当前任务时不在此任务位置上的两个人的位置(因为一定有一个人在此任务位置上): 不妨设初始位置p[0]=3 ...

  4. poj3468区间加减查找——树状数组区间修改查询

    题目:http://poj.org/problem?id=3468 增加一个更改量数组,施以差值用法则区间修改变为单位置修改: 利用公式可通过树状数组维护两个数组:f与g而直接求出区间和. 代码如下: ...

  5. SpringBoot @RequestBody 中文乱码

    今天突然想学习一下Restful风,详细的我就不赘述了,我的理解是同一个请求路径根据请求方式不同进行不同的处理 如四种提交方式,这里推荐一个插件Postman,可以模仿各种请求类型,自行百度安装吧 G ...

  6. USB相关资料

    http://www.usb.org/developers/defined_class/#BaseClass00h http://blog.csdn.net/lizzywu/article/detai ...

  7. shader之texture

    纹理坐标作为属性传递到顶点着色器 texture是OPENGL对象,包含一张或多张相同格式的图片. 它有2中用途: the source of a texture access from a Shad ...

  8. SVN needs-lock 设置强制只读属性【转】

    https://www.jianshu.com/p/5942ab19620b 设置后向svn服务器添加文件时,会自动带上svn:needs-lock属性,默认是只读的要签出才能修改,以避免不必要的编辑 ...

  9. UVA - 13022 Sheldon Numbers(位运算)

    UVA - 13022 Sheldon Numbers 二进制形式满足ABA,ABAB数的个数(A为一定长度的1,B为一定长度的0). 其实就是寻找在二进制中满足所有的1串具有相同的长度,所有的0串也 ...

  10. Linux之configure make make install

    正常的编译安装/卸载: 源码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install).   configure文件是一个可执行的脚本文件,它有很多选项, ...