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 ...
随机推荐
- 运维程序】简单的命令控制器(支持定时命令执行、重复定时任务命令和进程管理,开发这个小程序主要是为了方便管理服务进程)【个人github项目】
一.前言: command-controller 一个运维程序,简单的命令控制器(支持定时命令执行和重复定时命令,开发这个程序主要是为了方便管理服务进程) 本来是要用python做的,但是之前做ffm ...
- Jenkins持续集成环境搭建
1部署Jenkins Jenkins部署很简单,只需建立一个新应用,将Jenkins的war包部署进去,再分配好权限就可以了. 1.1创建应用 建立一个新Nginx应用:jenkins.com 1.2 ...
- mysql错误-修改mysql.sock位置
在Mysql下有时候会出现mysql.sock位置错误,导致无法链接数据库. mac下报错的时候: 首先修改my.cnf 位置在/etc/my.cnf下,假如没有的话,去/usr/locate/mys ...
- SIP业务基本知识
1.SIP业务基本知识 1.1 业务介绍会话初始协议(Session Initiation Protocol)是一种信令协议,用于初始.管理和终止网络中的语音和视频会话,具体地说就是用来生成.修改和终 ...
- springboot 1.5.x中的动态切换日志级别
logback是一套日志框架,由log4j的优化版,由同一个作者开发,在速度和性能上都超过其他日志框架,再结合slf4j,已成为当前最流行的日志框架. 一.springboot中使用logback s ...
- cocos2dx 3.0 用ClippingNode做游戏的新手引导
转自:http://blog.csdn.net/star530/article/details/20851263 本篇介绍的是用ClippingNode 做游戏的新手引导,额,或者说是做新手引导的一种 ...
- 11 Vue学习 headtop
1: HeaderTop.vue : 面包屑:el-breadcrumb 定义面包屑, separator是分隔符. el-breadcrumb-item: 是面包屑中用 分隔符 分开的多 ...
- RedisDesktopManager 可视化工具提示:无法加载键:Scan..
原因是redis的版本过低,window下的redis-cli.exe客户端输入 info 命令可看到该redis的版本,这个scan查看要redis2.80版本以上!!!!
- GET 和 POST两种调用方式
http://www.cnblogs.com/java-pan/archive/2012/02/26/httpclient-post-get.html 通过get和post方式调用http接口,总结如 ...
- 【241】◀▶IEW-Unit06
Unit 6 Advertising 多幅柱子在一幅图中的写作技巧 1.Model1图片分析 The bar chart contains information about the amount o ...