BZOJ_P1087&Codevs_P2451 [SCOI2005]互不侵犯King(状态压缩DP)
2016-02-05 11:29
411 查看
BZOJ传送门
Codevs传送门
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2385 Solved: 1399
[Submit][Status][Discuss]
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
3 2
Sample Output
16
HINT
Source
哦~~这题数据辣么小让我打上40s的表
然后可以提交介个 ps:内存有点大啊喂,缩小点就进BZOJ第一页了
Codevs传送门
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2385 Solved: 1399
[Submit][Status][Discuss]
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
3 2
Sample Output
16
HINT
Source
#include<cstdio> #include<iostream> using namespace std; #define N 10 int n,k,cnt;long long f [N*N][1<<N];long long ans; int m[1<<N]; inline int calc(long long x){ int res=0; for(int i=0;i<10;i++,x>>=1) if(x&1) res++; return res; } inline bool can1(int S){//单行是否可行 for(int i=0;i<N;i++) if(S&(1<<i)&&S&(1<<(i+1))) return false; return true; } inline bool can2(int S1,int S2){//两行是否可行 for(int i=0;i<N;i++) if((1<<i)&S1) if((1<<(i+1)&S2)||(1<<(i-1)&S2)||((1<<i)&S2)) return false; return true; } int main(){ scanf("%d%d",&n,&k);cnt=(1<<n); for(int i=0;i<cnt;i++) m[i]=calc(i);//计算每位1的数量 for(int S=0;S<cnt;S++){ if(m[S]<=k) f[0][m[S]][S]=1; } for(int i=1;i<n;i++){ for(int j=0;j<=k;j++) for(int S1=0;S1<cnt;S1++){//上一状态 if(m[S1]>j||(!can1(S1))) continue; for(int S2=0;S2<cnt;S2++){//当前状态 if(can1(S2)) if(j+m[S2]<=k&&can2(S1,S2)){ f[i][m[S2]+j][S2]+=f[i-1][j][S1]; } } } } for(int S=0;S<cnt;S++){ ans+=f[n-1][k][S]; } printf("%lld",ans); return 0; }
哦~~这题数据辣么小让我打上40s的表
#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define N 10 int n,k,cnt;long long f [N*N][1<<N];long long ans; int m[1<<N]; inline int calc(long long x){ int res=0; for(int i=0;i<10;i++,x>>=1) if(x&1) res++; return res; } inline bool can1(int S){ for(int i=0;i<N;i++) if(S&(1<<i)&&S&(1<<(i+1))) return false; return true; } inline bool can2(int S1,int S2){ for(int i=0;i<N;i++) if((1<<i)&S1) if((1<<(i+1)&S2)||(1<<(i-1)&S2)||((1<<i)&S2)) return false; return true; } int main(){ freopen("std.out","w",stdout); for(int p=1;p<=9;p++){ for(int q=0;q<p*p;q++){ n=p,k=q;memset(f,0,sizeof(f)); cnt=(1<<n);ans=0; for(int i=0;i<cnt;i++) m[i]=calc(i); for(int S=0;S<cnt;S++){ if(m[S]<=k) f[0][m[S]][S]=1; } for(int i=1;i<n;i++){ for(int j=0;j<=k;j++) for(int S1=0;S1<cnt;S1++){//上一状态 if(m[S1]>j||(!can1(S1))) continue; for(int S2=0;S2<cnt;S2++){//当前状态 if(can1(S2)) if(j+m[S2]<=k&&can2(S1,S2)){ f[i][m[S2]+j][S2]+=f[i-1][j][S1]; } } } } for(int S=0;S<cnt;S++){ ans+=f[n-1][k][S]; } printf("%I64d,",ans); } for(int i=p*p+1;i<81;i++) printf("0,"); } return 0; }
然后可以提交介个 ps:内存有点大啊喂,缩小点就进BZOJ第一页了
#include<cstdio> long long f[]={1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,9,16,8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,16,78,140,79,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,25,228,964,1987,1974,978,242,27,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,36,520,3920,16834,42368,62266,51504,21792,3600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,49,1020,11860,85275,397014,1220298,2484382,3324193,2882737,1601292,569818,129657,18389,1520,64,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,64,1806,29708,317471,2326320,12033330,44601420,119138166,229095676,314949564,305560392,204883338,91802548,25952226,4142000,281571,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,81,2968,65240,962089,10087628,77784658,450193818,1979541332,6655170642,17143061738,33787564116,50734210126,57647295377,49138545860,31122500764,14518795348,4959383037,1237072414,224463798,29275410,2673322,163088,6150,125,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int main(){ int n,k; scanf("%d%d",&n,&k); printf("%lld",f[(n-1)*81+k-(n-1)]); return 0; }
相关文章推荐
- C++ 学习之函数重载、基于const的重载
- 车联网API——位置、距离
- noip2004-合并果子 2008.10.22
- PHP连接MSSQL方法汇总
- junit设计模式--命令者模式
- junit设计模式--命令者模式
- OpenGL编程指南之阅读笔记 第二章 状态管理和绘制几何物体
- Eclipse一步一步搭建SSM+Maven
- hadoop2.5.2安装部署
- SharePoint2016 New Feature (Preview) - 支持ODF File Template
- noip2005篝火晚会 2008.10.18
- SQL Server命令行
- noip2005-奖学金 2008.10.17
- 搭建lamp环境Q&A
- FFT与NTT
- Eclispe 生成JAVADOC 报java.lang.IllegalArgumentException解决方案
- Oracle12c Release1安装图解(详解)
- usaco numgrid 2008.9.29
- 系统设计以及javascript笔记:用户行为分析研究之数据采集
- 梯度下降优化算法概述