SGU 225
来源:互联网 发布:mac版itunes制作铃声 编辑:程序博客网 时间:2024/05/06 03:20
题意:给出一个n*n的棋盘和k个马,问有多少种放的方法使得马互不相攻击。
题解:首先很容易想到设dp[u][v][i][j]表示前i行,用了j个马,第i行的状态为v,前一行的状态为u。
dp[u][v][i][j]+=dp[i][u][i-1][j-cnt[v]]且v不与i,u冲突。
判冲突的话可以这样,前两行左移1位&当前行,为1则冲突,然后右移一样的。前一行就左右移两位&当前行。
但这样做会爆空间,考虑u,v压到一个int 内,再对行数用滚动数组,再n=8,9,10打表。ps(打表调得我好苦啊);
%%%__debug。
#include<cstdlib>#include<cstring>#include<cstdio>#include<algorithm>#include<iostream>using namespace std;const int MAXS=1025,base=256,MAXN=11,MAXST=70000,MAXK=51;typedef long long ll;ll dp[MAXST][2][MAXK];int lim,tot=0,st[MAXST],cnt[MAXST];ll list_10[110]={1LL,100LL,4662LL,135040LL,2732909LL,41199404LL,481719518LL,4491423916LL,34075586550LL,213628255072LL,1120204619108LL,4961681221524LL,18715619717199LL,60541371615660LL,168976761361446LL,409191804533576LL,864172675710439LL,1599730843649564LL,2609262108838924LL,3770687313420780LL,4857550050070531LL,5616928666465104LL,5874943705896600LL,5604501518609804LL,4917655076255841LL,3999855946779732LL,3034690618677388LL,2156485957257040LL,1437827591264317LL,899278231344296LL,526753407546620LL,288274613750624LL,146990556682887LL,69626509814580LL,30542906352994LL,12366448408056LL,4604442057431LL,1569983914256LL,487876545370LL,137395261280LL,34831261750LL,7884855000LL,1578162590LL,275861904LL,41455966LL,5246412LL,543534LL,44244LL,2652LL,104LL,2};ll list_9[82]={1LL,81LL,3016LL,68796LL,1080942LL,12472084LL,110018552LL,762775440LL,4241252429LL,19206532478LL,71707869632LL,222946143752LL,582155146204LL,1286247689414LL,2421159140764LL,3908273840366LL,5446391581062LL,6599640204257LL,7010436668992LL,6589213734278LL,5537849837497LL,4207779106033LL,2920161348852LL,1865346129716LL,1101125592067LL,600730512987LL,302041066250LL,139345014744LL,58692638521LL,22451454400LL,7755194754LL,2403337080LL,663103709LL,161373907LL,34237130LL,6238414LL,957145LL,120334LL,11914LL,872LL,42LL,1}; ll list_8[65]={1LL,64LL,1848LL,32084LL,376560LL,3184708LL,20202298LL,98796304LL,379978716LL,1167053680LL,2897726604LL,5876860140LL,9825415557LL,13660238780LL,15932672964LL,15737653004LL,13304668385LL,9742722088LL,6260518246LL,3574590840LL,1830733371LL,844203844LL,349524138LL,128874944LL,41833846LL,11792736LL,2840224LL,572432LL,93840LL,12004LL,1122LL,68LL,2LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL,0LL};int hashed(int x,int y){ return x*base+y;}int get1(int x){ int tmp=x,c=0; while(tmp) { if(tmp&1)c++; tmp>>=1; } return c;}void init(){ memset(dp,0,sizeof(dp)); memset(cnt,0,sizeof(cnt)); memset(st,0,sizeof(st)); tot=0; for(int i=0;i<lim;i++) for(int j=0;j<lim;j++) { if(!((i<<2&j)||(i>>2&j))) st[tot++]=hashed(i,j); } for(int i=0;i<MAXST;i++)cnt[i]=get1(i);}void clear(int p,int& k){ for(int i=0;i<MAXST;i++) for(int j=0;j<=k;j++)dp[i][p][j]=0;}ll work(int n,int k,int t){ lim=1<<n; init();dp[0][0][0]=1; int p=1; for(int i=1;i<=n;i++) { clear(p,k); for(int j=0;j<=k;j++) { for(int s=0;s<tot;s++)if(cnt[st[s]]<=k) { if(i==1&&st[s]!=0)break; if(i==2&&st[s]>=base)break; for(int l=0;l<1<<n;l++) { int x=st[s]/base,y=st[s]%base; if(!((x<<1&l)||(x>>1&l)||(y<<2&l)||(y>>2&l))) if(j>=cnt[l]) { ll tmp=dp[st[s]][p^1][j-cnt[l]]; dp[y*base+l][p][j]+=tmp; } } } } p^=1; } ll ans=0; for(int i=0;i<tot;i++) if(cnt[st[i]]<=k) ans+=dp[st[i]][n&1][k]; return ans;}int main(){ freopen("225.in","r",stdin); freopen("w.out","w",stdout); int n,k; scanf("%d %d",&n,&k); if(n==10)cout<<list_10[k]<<endl; else if(n==9)cout<<list_9[k]<<endl; else if(n==8)cout<<list_8[k]<<endl; else if(k>MAXK)cout<<0<<endl; else printf("%I64d",work(n,k,1));}
1 0
- sgu 225
- SGU 225
- SGU
- SGU
- SGU
- SGU
- SGU
- SGU
- (SGU
- SGU
- SGU
- SGU
- SGU
- SGU
- SGU
- SGU
- sgu 225 Little Knights 状态压缩dp
- sgu 120
- 树的宽度
- Hello World
- Git忽略文件及Unity下的ignore配置
- unity animation动画效果
- linux系统环境变量配置
- SGU 225
- Windows下安装MongoDb
- swift基础教程——基本运算符
- 【云快讯】《Salesforce云服务“改头换面”,并将推出新的金融服务云》
- [译]Quora是如何维持高质量代码的
- python学习笔记
- SVN服务器搭建02---SVN服务器软件搭建(Ubuntu14.04)
- Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)
- 拍照及从相册中选择