JZOJ 3059. 雕塑
题目
分析
- 这道题真是让我笑死
- n=20,m=10 状压可能过不了哦
- 算了试试吧
- 结果拿了九十
- 然后还错了一个点
- 出题人有想啥,卡状压好吧我服了
- 结果是WA,之前的大佬都是打标过的??
- xswl
- 设f[i][j]为到当前第i行,前i-1行状态为j
- 然后先把初始化1打出来
- 方程为 f[i][j|(1<<k-1)]+=f[i-1][j];
- 因为我们的状态是只有上一行影响所以可以开滚动数组
- x^=1; __builtin_popcount(j)这东西能直接得到j在二进制下1的个数
代码
1 #include<iostream> 2 using namespace std; 3 int n,m; 4 int map[30][30]; 5 long long f[2][1<<20+1]; 6 int a[21]; 7 int main () 8 { 9 cin>>n>>m; 10 for (int i=1,x,y;i<=m;i++) cin>>x>>y,map[x][y]=1; 11 for (int i=1;i<=n;i++) 12 for (int j=1;j<=n;j++) 13 a[i]=(a[i]<<1)+map[i][j]; 14 int maxn=(1<<n)-1; 15 int x=1; 16 for (int i=1;i<=n;i++) 17 if (!(a[1]&(1<<i-1))) 18 f[x][(1<<i-1)]=1; 19 for (int i=2;i<=n;i++) 20 { 21 x^=1; 22 for (int j=1;j<=maxn;j++) 23 { 24 if (__builtin_popcount(j)==i-1) 25 { 26 for (int k=1;k<=n;k++) 27 { 28 if (!(j&(1<<k-1))&&!(a[i]&(1<<k-1))) 29 f[x][j|(1<<k-1)]+=f[x^1][j]; 30 } 31 } 32 } 33 } 34 long long ans=0; 35 for (int i=1;i<=maxn;i++) 36 if (__builtin_popcount(i)==n) 37 ans+=f[x][i]; 38 cout<<ans; 39 }
为何要逼自己长大,去闯不该闯的荒唐