最近题目都有状态压缩,我是蒟蒻,并不会状态压缩
然后我决定学了!
然后发现我学不来。
OI-WIKI上的界面给我推荐了这道题https://oi-wiki.org/dp/state/
状态压缩入门题,可惜我不会
下面是OIWIKI的代码
#include<bits/stdc++.h> using namespace std; int read(){//读入优化 int x=0,w=1;char ch=0; while(ch<'0' || ch>'9'){if(ch=='-') w=-1;ch=getchar();} while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*w; } int main(){ int m=read(),n=read();//题中行数和列数 int maxn=1<<n;//上界 int Type[maxn+10];//储存压缩后的每行可能的状态 int top=0; int Soil[m+10]={0};//每行土地的情况 int f[20][maxn+10];//储存答案的数组 for (int i=0;i<maxn;i++){//存储每行可能的状态 if (i&(i<<1)) continue; Type[++top]=i; } for (int i=1;i<=m;i++) for (int l=1;l<=n;l++){ int k=read(); if (k==0) Soil[i]+=1<<(n-l);//反向建图,0置为1,和Type数组中情况相对,便于使用位运算检查 //因为先读入的是左侧的土地,二进制中左侧的'1'代表的值更大,所以将第l个读入的数存在第l位应+(1<<(n-l)) } memset(f,0,sizeof(f)); for (int i=1;i<=top;i++) if (!(Type[i]&Soil[1])) f[1][i]=1; for (int i=2;i<=m;i++)//穷举层数 for (int l=1;l<=top;l++){//穷举本层 if (Type[l]&Soil[i]) continue;//判断是否符合 for (int j=1;j<=top;j++){//穷举上一层 if (Type[j]&Soil[i-1]) continue;//判断是否符合 if (Type[l]&Type[j]) continue;//判断是否符合 f[i][l]=(f[i][l]+f[i-1][j])%100000000; } } int ans=0; for (int i=1;i<=top;i++) ans=(ans+f[m][i])%100000000;//累加答案 cout<<ans;//输出 }
然后我抄袭了题解,AC了
总结:我太菜了