首页 > 其他 > 详细

[CF295C] Greg and Friends - dp

时间:2020-08-29 18:59:46      阅读:64      评论:0      收藏:0      [点我收藏+]

Description

有一只载重为 \(k \le 5\times10^3\) 的船在两岸之间往返,有 \(n \le 50\) 个人要过河,每个人的体重只能使 \(50\)\(100\),问最少的来回次数以及对应的方案数。

Solution

\(f[i][j][0/1]\) 表示对岸已经有 \(i\)\(50\)\(j\)\(100\) 时最少的航行次数,\(g[i][j][0/1]\) 为对应的方案数

枚举本次走的 \(k,l\) 个数,利用组合数进行转移即可

最多转移 \(2n\) 轮一定能完事,复杂度 \(O(n^5)\)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 55;
const int dbg = 1;
const int mod = 1e9+7;

int n,m,a,b;
int f[N][N][2],g[N][N][2],nCr[N][N],e[N][N][2];

void readall()
{
    ios::sync_with_stdio(false);

    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        int t;
        cin>>t;
        if(t==50) ++a;
        else ++b;
    }
}

void update(int a,int b,int &c,int &d,int &e)
{
    if(a<c)
    {
        c=a;
        d=b;
        e=1;
    }
    else if(a==c)
    {
        d+=b;
        d%=mod;
    }
}

void presolve()
{
    nCr[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        nCr[i][0]=1;
        for(int j=1;j<=i;j++)
        {
            nCr[i][j]=(nCr[i-1][j]+nCr[i-1][j-1])%mod;
        }
    }
}

void solve()
{
    memset(f,0x3f,sizeof f);
    f[0][0][0]=0;
    memset(g,0xff,sizeof g);
    g[0][0][0]=1;
    e[0][0][0]=1;
    for(int v=1;v<=2*n;v++)
    {
        for(int i=0;i<=a;i++)
        {
            for(int j=0;j<=b;j++)
            {
                for(int k=0;i+k<=a;k++)
                {
                    for(int l=0;j+l<=b;l++)
                    {
                        if(k==0&&l==0) continue;
                        if(k*50+l*100>m) continue;
                        update(f[i][j][0]+1,g[i][j][0]*nCr[a-i][k]%mod*nCr[b-j][l]%mod,f[i+k][j+l][1],g[i+k][j+l][1],e[i+k][j+l][1]);
                    }
                }
            }
        }
        for(int i=0;i<=a;i++)
        {
            for(int j=0;j<=b;j++)
            {
                for(int k=0;i-k>=0;k++)
                {
                    for(int l=0;j-l>=0;l++)
                    {
                        if(k==0&&l==0) continue;
                        if(k*50+l*100>m) continue;
                        update(f[i][j][1]+1,g[i][j][1]*nCr[i][k]%mod*nCr[j][l]%mod,f[i-k][j-l][0],g[i-k][j-l][0],e[i-k][j-l][0]);
                    }
                }
            }
        }
        if(f[a][b][1]<1e9)
        {
            cout<<f[a][b][1]<<endl<<g[a][b][1]<<endl;
            return;
        }
    }
    {
        cout<<-1<<endl<<0<<endl;
    }
}

signed main()
{
    readall();
    presolve();
    solve();
}

[CF295C] Greg and Friends - dp

原文:https://www.cnblogs.com/mollnn/p/13582648.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!