日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

状压dp 棋盘问题

發布時間:2024/7/5 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 状压dp 棋盘问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

棋盤問題1

問題描述

n×n(n20)

的方格棋盤上放置n個車(可以攻擊所在行、列),求使它們不能互相攻擊的方案總數。

輸入格式

一行,若干個1到20之間的整數。

輸出格式

若干行,對于輸入的每個整數,輸出其方案數。

樣例輸入

3 2

樣例輸出

6 2

限制與約定

時間限制:1s

空間限制:128MB

#include<iostream> #include<cstring> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long f[1<<20]; int main() {int n;while(scanf("%d",&n)==1){memset(f,0,sizeof(f));f[0]=1;for(long long i=1;i<=(1<<n);i++)for(long long t=i;t>0;t-=t&-t)f[i]+=f[i&~(t&-t)]; cout<<f[(1<<n)-1]<<endl;}return 0; }

棋盤問題2

問題描述

n×n(n20)

的方格棋盤上放置n 個車(可以攻擊所在行、列),某些格子不能放,求使它們不能互相攻擊的方案總數。

輸入格式

給你一個n和m,分別表示棋盤的大小,不能放的格子總數。接下來是m行坐標,表示不能放置的位子。

輸出格式

符合條件的方案總數。

輸入樣例1

3 2 1 2 2 3

輸出樣例1

3

輸入樣例2

4 1 1 1

輸出樣例2

18

限制與約定

時間限制:1s

空間限制:128MB

#include<iostream> #include<cstring> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long f[1<<20],s[25]; int main() {int n,m;while(scanf("%d%d",&n,&m)!=EOF){memset(f,0,sizeof(f));memset(s,0,sizeof(s));for(int i=0,a,b;i<m;i++){cin>>a>>b;s[a]+=1<<(b-1);}f[0]=1;for(long long i=1;i<=(1<<n);i++){int num=0;for(long long t=i;t>0;t-=t&-t) num++;for(long long t=i;t>0;t-=t&-t)if(!(s[num]&(t&-t)))f[i]+=f[i&~(t&-t)];}cout<<f[(1<<n)-1]<<endl;}return 0; }

棋盤問題3

問題描述

給出一個n×m

的棋盤(n、m80,n×m80

),要在棋盤上放k(k≤20)個棋子, 使得任意兩個棋子不相鄰(相鄰指上下左右四個方向)。求可以放置的總的方案數。

輸入格式

一行三個整數n,m,k,表示棋盤大小為n行m列,棋盤上放置k個棋子。

輸出格式

一個整數表示方案數。

輸入樣例1

3 3 2

輸出樣例1

24

輸入樣例2

2 2 2

輸出樣例2

2

輸入樣例3

20 1 2

輸出樣例3

171

限制與約定

時間限制:1s

空間限制:128MB

?

#include<iostream> #include<cstring> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long num,f[21][1<<9][21],s[1<<10],c[1<<10],n,m,kl; void dfs(int ans,int pos,int flag) {if(pos>m){s[++num]=ans;c[num]=flag;return;}dfs(ans,pos+1,flag);dfs(ans+(1<<pos-1),pos+2,flag+1); } int main() {while(scanf("%lld%lld%lld",&n,&m,&kl)!=EOF){if(n<m) swap(n,m);memset(f,0,sizeof(f));num=0;dfs(0,1,0);for(int i=1;i<=num;i++)f[1][s[i]][c[i]]=1;for(long long i=2;i<=n;i++)for(long long j=1;j<=num;j++)for(long long l=1;l<=num;l++)if(!(s[l]&s[j]) )for(int k=0;k<=kl;k++)if(k>=c[j]) f[i][s[j]][k]+=f[i-1][s[l]][k-c[j]];long long ans=0;for(int i=1;i<=num;i++)ans+=f[n][s[i]][kl];cout<<ans<<endl;}return 0; }

棋盤問題4

問題描述

n×n(n10)

的棋盤上放k 個國王(可攻擊相鄰的8 個格子),求使它們無法互相攻擊的方案數。

輸入格式

一行兩個整數n,k,棋盤大小為n行n列,棋盤上放置k個棋子。

輸出格式

一個整數表示方案數。

輸入樣例1

2 1

輸出樣例1

4

輸入樣例2

3 2

輸出樣例2

16

限制與約定

時間限制:1s

空間限制:128MB

#include<iostream> #include<cstring> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long num,f[11][1<<10][15],s[1<<11],c[1<<11],n,kl; void dfs(int ans,int pos,int flag) {if(pos>n){s[++num]=ans;c[num]=flag;return;}dfs(ans,pos+1,flag);dfs(ans+(1<<pos-1),pos+2,flag+1); } int main() {while(scanf("%lld%lld",&n,&kl)!=EOF){memset(f,0,sizeof(f));num=0;dfs(0,1,0);for(int i=1;i<=num;i++)f[1][s[i]][c[i]]=1;for(long long i=2;i<=n;i++)for(long long j=1;j<=num;j++)for(long long l=1;l<=num;l++)if(!(s[l]&s[j]) && !((s[l]<<1) & s[j]) && !((s[l]>>1)&s[j]))for(int k=0;k<=kl;k++)if(k>=c[j]) f[i][s[j]][k]+=f[i-1][s[l]][k-c[j]];long long ans=0;for(int i=1;i<=num;i++)ans+=f[n][s[i]][kl];cout<<ans<<endl;}return 0; }

?

轉載于:https://www.cnblogs.com/hfang/p/11239848.html

總結

以上是生活随笔為你收集整理的状压dp 棋盘问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。