求助,样例没过 AC#1
查看原帖
求助,样例没过 AC#1
363145
Dino_Andy233楼主2022/7/26 10:56

找不出来问题了 QWQ

#include<bits/stdc++.h>
using namespace std;
//1.判断一个数字x二进制下第i位是不是等于1。(最低第1位)
//方法:if(((1<<(i-1))&x)>0) 将1左移i-1位,相当于制造了一个只有第i位 上是1,其他位上都是0的二进制数。然后与x做与运算,如果结果>0, 说明x第i位上是1,反之则是0。

//2.将一个数字x二进制下第i位更改成1。
//方法:x=x|(1<<(i-1)) 证明方法与1类似。

//3.将一个数字x二进制下第i位更改成0。
//方法:x=x&~(1<<(i-1))

//4.把一个数字二进制下最靠右的第一个1去掉。
//方法:x=x&(x-1) 

const int maxn=155;
long long f[11][maxn][maxn],ans;
int a[maxn],s[maxn];
int N,K,S;
void pre(){//预处理 状压 
	S=0;
	ans=0;
	int cnt; 
	memset(f,0,sizeof(f));
	for(int i=0;i<(1<<N);i++){//枚举每行状态 
		if(i&(i<<1)) continue;//检查当前行状态是否冲突 
		cnt=0;
		for(int j=0;j<N;j++)
			if(i&(1<<j)) cnt++;
		s[++S]=0; //可用状态i,总计可用状态S状压 
		a[S]=cnt; //每种状态放置国王的数量 
	}
}
void dp(){//dp 核心部分
	f[0][1][0]=1; //初始化, 第0行放0个国王的方案为1
	for(int i=1;i<=N;i++)
		for(int j=1;j<=S;j++)
			for(int k=0;k<=K;k++)
				if(k>=a[j])
					for(int t=1;t<=S;t++)
						if(!(s[t]&s[j]) && !(s[t]&(s[j]<<1)) && !(s[t]&(s[j]>>1))) //无冲突
							f[i][j][k]+=f[i-1][t][k-a[j]];
	for(int i=1;i<=S;i++) ans+=f[N][i][K]; //放置K个国王的方案数总和
	cout<<ans<<endl; 
}
int main(){
	cin>>N>>K;
	pre();
	dp();
	return 0;
}
2022/7/26 10:56
加载中...