例题1:种植方案 link
思路:
状压模板
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=100000000;
const int N=1e6;
int n, m, map[1<<13+10], a, f[20][1<<13+10], ans, tot, s[10010];
void dfs(int ans, int dep)
{
if(dep > m) {
s[++tot]=ans; return;}
dfs(ans, dep+1);
dfs(ans+(1 << (dep - 1)),dep+2);
}
int main()
{
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
scanf("%d", &a);
if(a==0) map[i]+=1 << (j - 1);
}
dfs(0,1);
for(int i=1; i<=tot; i++)
if(!(map[1] & s[i])) f[1][s[i]]=1;
for(int i=2; i<=n; i++)
for(int j=1; j<=tot; j++)
if(!(map[i] & s[j]))
for(int k=1; k<=tot; k++)
if(!(s[j] & s[k]))
f[i][s[j]]=(f[i][s[j]]+f[i-1][s[k]])%MAX;
for(int i=1; i<=tot; i++) ans=(ans+f[n][s[i]])%MAX;
printf("%d", ans%MAX);
return 0;
}
例题2:最短路径 link
思路:
设f[i][j]表示现在走到i点,所有点的遍历状态j(1表示走过,0反之亦然)
f [ i ] [ j ] = m i n ( f [ k ] [ j x o r ( 1 < < i ) ] + a [ i