Gym 102219 F Military Class —— 记忆化搜索

This way

题意:

现在有两列士兵,第一列的第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));
}

发布了554 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/104275079
今日推荐