P4876 近似排列计数50
时间限制: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-一维
#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的更多相关文章
- BZOJ 4517: [Sdoi2016]排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 911 Solved: 566[Submit][Status ...
- bzoj-4517 4517: [Sdoi2016]排列计数(组合数学)
题目链接: 4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 846 Solved: 530[Submit][ ...
- 数学(错排):BZOJ 4517: [Sdoi2016]排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 693 Solved: 434[Submit][Status ...
- 【数论·错位排列】bzoj4517 排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 1428 Solved: 872[Submit][Statu ...
- bzoj4517排列计数 错排+组合
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 1491 Solved: 903[Submit][Statu ...
- BZOJ_4517_[Sdoi2016]排列计数_组合数学
BZOJ_4517_[Sdoi2016]排列计数_组合数学 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[ ...
- BZOJ 4517--[Sdoi2016]排列计数(乘法逆元)
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 1727 Solved: 1067 Description ...
- 洛谷P4071 [SDOI2016] 排列计数 [组合数学]
题目传送门 排列计数 题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m ...
- [BZOJ4517][SDOI2016]排列计数(错位排列)
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 1616 Solved: 985[Submit][Statu ...
随机推荐
- div靠右浮动案例
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- bzoj1177&p3625 [APIO2009]采油区域p[大力讨论]
我好菜菜啊. 给定矩形,从中选出三个边长K的正方形互不重叠,使得覆盖到的数总和最大. 想的时候往dp上钻去了..结果一开始想了一个错的dp,像这样 /************************* ...
- tyvj1061移动服务——DP
题目:http://www.joyoi.cn/problem/tyvj-1061 DP记录状态为当前任务时不在此任务位置上的两个人的位置(因为一定有一个人在此任务位置上): 不妨设初始位置p[0]=3 ...
- poj3468区间加减查找——树状数组区间修改查询
题目:http://poj.org/problem?id=3468 增加一个更改量数组,施以差值用法则区间修改变为单位置修改: 利用公式可通过树状数组维护两个数组:f与g而直接求出区间和. 代码如下: ...
- SpringBoot @RequestBody 中文乱码
今天突然想学习一下Restful风,详细的我就不赘述了,我的理解是同一个请求路径根据请求方式不同进行不同的处理 如四种提交方式,这里推荐一个插件Postman,可以模仿各种请求类型,自行百度安装吧 G ...
- USB相关资料
http://www.usb.org/developers/defined_class/#BaseClass00h http://blog.csdn.net/lizzywu/article/detai ...
- shader之texture
纹理坐标作为属性传递到顶点着色器 texture是OPENGL对象,包含一张或多张相同格式的图片. 它有2中用途: the source of a texture access from a Shad ...
- SVN needs-lock 设置强制只读属性【转】
https://www.jianshu.com/p/5942ab19620b 设置后向svn服务器添加文件时,会自动带上svn:needs-lock属性,默认是只读的要签出才能修改,以避免不必要的编辑 ...
- UVA - 13022 Sheldon Numbers(位运算)
UVA - 13022 Sheldon Numbers 二进制形式满足ABA,ABAB数的个数(A为一定长度的1,B为一定长度的0). 其实就是寻找在二进制中满足所有的1串具有相同的长度,所有的0串也 ...
- Linux之configure make make install
正常的编译安装/卸载: 源码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install). configure文件是一个可执行的脚本文件,它有很多选项, ...