zoukankan      html  css  js  c++  java
  • 【Atcoder】ARC107 D

    D - Number of Multisets

    题目大意

    给出 (n)(k) ,问 (n) 个数字的和为 (k) 的方案数有多少。

    数字可以取({1,frac{1}{2},frac{1}{4},frac{1}{8},frac{1}{16},....})

    题解

    考虑两种方案,第一种不取 (1) ,第二种取 (1)

    (dp[n][k]) 表示 (n) 个数字组成 (k) 的方案。

    当不取 (1) 的时候,可以取的区间为 ({frac{1}{2},frac{1}{4},frac{1}{8},frac{1}{16},....}),乘上一个 (2),方案数即 (dp[n][2*k])

    当取 (1) 的时候,问题转化为:(dp[n-1][k-1])

    我们得到转移方程 (dp[n][k]=dp[n-1][k-1]+dp[n][k*2])

    记忆化搜索。

    代码

    //#include<bits/stdc++.h>
    #include <algorithm>
    #include <iostream>
    #include <map>
    #include <set>
    #include <stack>
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    
    using namespace std;
    
    #define pb push_back
    typedef long long ll;
    typedef unsigned long long ull;
    const int inf = 0x3f3f3f3f;
    const int mod = 998244353;
    const int seed = 233;
    const int N = 1e7 + 10;
    
    int dp[3010][3010];
    
    int dfs(int n,int k)
    {
        if(n<k) return 0;
        if(dp[n][k]!=-1) return dp[n][k];
        if(n==k) return dp[n][k]=1;
        if(k==0) return 0;
        return dp[n][k]=dfs(n-1,k-1)%mod+dfs(n,2*k)%mod;
    }
    
    int main()
    {
        memset(dp,-1,sizeof(dp));
        int n,k;
        scanf("%d%d",&n,&k);
        printf("%d
    ",dfs(n,k)%mod);
        return 0;
    }
    
  • 相关阅读:
    原创 动态卷积
    BZOJ1565 植物大战僵尸
    BZOJ1143 [CTSC2008] 祭祀river
    BZOJ3438 小M的作物
    BZOJ3144 [HNOI2013]切糕
    BZOJ2039 [2009国家集训队]employ人员雇佣
    BZOJ1066[SCOI2007]蜥蜴
    BZOJ3874 codevs3361 宅男计划
    Codeforces Round #343 (Div. 2)
    [转]后缀自动机(SAM)
  • 原文地址:https://www.cnblogs.com/valk3/p/14095834.html
Copyright © 2011-2022 走看看