BZOJ1087&&洛谷P1869[SCOI2005]互不侵犯

人生中的第一道状压dp(照着题解写的(捂脸))

先dfs预处理出每种情况下的二进制(状压不是用01描轮廓吗),然后枚举每行的选哪个,不用考虑他的上一行,因为这行是从上一行转移下来的,我们只需要判断和下一行冲不冲突,不冲突就累加答案

初始化时第一行的美种情况的方案数都是1,最后去最后一层累加答案

代码(从头到尾抄了一遍,虽然不是直接交的题解,但是还是好羞耻(捂脸))

//By AcerMo
#include
#include
#include
#include
#include
using namespace std;
const int M=2050;
long long int f[10][M][100];
int push[M],get[M];
int n,m,cnt=0;
inline int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
	return x;
}
inline void dfs(int emm,int sum,int x)
{
	if (x>=n){get[++cnt]=emm;push[cnt]=sum;return ;}//到了最底层 
	dfs(emm,sum,x+1);//不选当前点,那么找它下一个 
	dfs(emm+(1<=push[j];e--) f[i][j][e]+=f[i-1][k][e-push[j]];//累加 
	long long int ans=0;
	for (int i=1;i<=cnt;i++) ans+=f[n][i][m];//在最底层统计答案 
	cout<

你可能感兴趣的:(动态规划)