题意:
现在有两列士兵,第一列的第i个人可以与第二列的第i-e到第i+e的人匹配。但是有一些人不能相互匹配。问你有多少种匹配方法。
题解:
首先数据范围是2000,那么第一个想到的是区间DP,但是不对,因为它没有办法分割成多个区间。然后看见它的e是4,应该是个状压dp。那么久可以设dp[i][s]表示到第i个人的时候,它可以匹配的位置的状态是s的时候,答案的个数。然后由于它是枚举e来搜索的,那么前面的状态必然用到多次后面的状态,所以应该是记忆化搜索。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
const int N=2e3+5;
ll dp[N][(1<<9)+5];
bool mp[N][N];
int n,e,k,x,y;
ll dfs(int pos,int s){
if(pos>n)
return 1;
s>>=1;
if(~dp[pos][s])
return dp[pos][s];
ll ans=0;
for(int i=0;i<=e*2;i++){
if(pos-e+i>=1&&pos-e+i<=n&&!(s&(1<<i))&&!mp[pos][pos-e+i]){
int ne=s|(1<<i);
ans=(ans+dfs(pos+1,ne))%mod;
}
}
dp[pos][s]=ans;
return ans;
}
int main()
{
memset(dp,-1,sizeof(dp));
scanf("%d%d%d",&n,&e,&k);
for(int i=1;i<=k;i++)
scanf("%d%d",&x,&y),mp[x][y]=1;
printf("%lld",dfs(1,0));
}