BZOJ 4742: [Usaco2016 Dec]Team Building 动态规划

本文介绍了一种使用二维动态规划解决身高匹配问题的方法。通过定义状态$f[i][j][k]$表示$fj$扫到$i$,$fp$扫到$j$,已经选了$k$个身高的所有状态的前缀和,利用容斥原理更新状态,最终求得$n$个男生与$m$个女生中选择$K$对身高匹配的方案数。

令 $f[i][j][k]$ 表示 $fj$ 扫到 $i$,$fp$ 扫到 $j$,已经选了 $k$ 个身高的所有状态的前缀和.  

我们有 $f[i][j][k]=f[i-1][j][k]+f[i][j-1][k]-f[i-1][j-1][k]$,这步是一个简单的容斥.    

然后如果有 $fj[i]=fp[j]$ 的话可以直接得到:$f[i][j][k]=f[i][j][k]+f[i-1][j-1][k-1]$  

code:

#include <cstdio>  
#include <cstring>
#include <algorithm>  
#define N 1007 
#define ll long long 
#define mod 1000000009   
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;   
ll f[N][N][11]; 
int fj[N],fp[N]; 
int main() 
{ 
    // setIO("input");     
    int i,j,n,m,K; 
    scanf("%d%d%d",&n,&m,&K);   
    for(i=1;i<=n;++i) scanf("%d",&fj[i]); 
    for(i=1;i<=m;++i) scanf("%d",&fp[i]);           
    for(i=0;i<=n;++i) for(j=0;j<=m;++j)  f[i][j][0]=1;  
    for(int k=1;k<=K;++k) 
    {     
        for(i=1;i<=n;++i) 
        {
            for(j=1;j<=m;++j) 
            {
                (f[i][j][k]+=(f[i-1][j][k]+f[i][j-1][k]-f[i-1][j-1][k]+mod)%mod)%=mod;           
                if(fj[i]>fp[j]) (f[i][j][k]+=f[i-1][j-1][k-1])%=mod; 
            }
        }
    }
    printf("%lld\n",f[n][m][K]);  
    return 0; 
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值