线性dp

C - Tak and Cards (atcoder.jp)

 

 

解:

设 dp[i][j][k]表示为:正在处理第i张牌,从一共i张牌中选j张,组成的数为 k

初始状态:dp[0][0][0]=1

if x+k<= A*n, dp[i+1][j+1][x+k]+=dp[i][j][k]

最后 累加,dp[n][j][A*j],1<=j<=n

#include<bits/stdc++.h>
using ll=long long;
void solve()
{
    int n,A;
    std::cin>>n>>A;
    std::vector<ll>x(n);
    for(auto&i:x)std::cin>>i;
    std::vector dp(n+1,std::vector<std::vector<ll>>(n+1,std::vector<ll>(A*n+1)));
    dp[0][0][0]=1;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=i;j++)
        {
            for(int k=0;k<=A*n;k++)
            {
                dp[i+1][j][k]+=dp[i][j][k];
                if(x[i]+k<=A*n)
                {
                    dp[i+1][j+1][k+x[i]]+=dp[i][j][k];
                }
            }
        }
    }
    ll ans=0;
    for(int i=1;i<=n;i++)ans+=dp[n][i][A*i];
    std::cout<<ans<<"\n";
}
int main()
{
    std::cin.tie(nullptr)->sync_with_stdio(false);
    solve();
    return 0;
}

 

posted @ 2023-03-15 19:23  惣聪术  阅读(21)  评论(0)    收藏  举报