zoukankan      html  css  js  c++  java
  • 4.6 每日一题题解

    三角形

    涉及知识点:

    • 背包dp

    solution:

    • 背包是dp算法中非常经典的一个问题(如果打算学dp的同学必须要学会背包问题),具体的大家可以看我发在群里的背包九讲pdf
    • 关于这道题目,我们可以对每一个宝箱做一个背包
    • 题目要求从每一个宝箱中有且只能取一个,所以设dp[i][j]为枚举到第i个宝箱,可以获得钱数等于j的方案数
    • 那么转移方程就等于 dp[ i ][ z ] += dp[ i-1 ][ z - a[ i ][ j ] ] ,初始化dp[ 0 ][ 0 ] = 1
    • i代表前i个宝箱,z代表可以获得z钱,a[ i ][ j ]代表枚举的第i个宝箱的第j个钱,dp[ i ][ z ]就等于前i个宝箱可以获得z钱的方案数
    • j的范围是0~10000,最后从小到达枚举dp[ n ][ j ],代表前n个宝箱中可以获得钱数等于j的方案数,不断和k做差就得到了答案

    std:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn = 105;
    int a[maxn][maxn],dp[maxn][maxn*maxn],len[maxn];
    int main()
    {
        int n , k;
        cin>>n>>k;
        for(int i=1;i<=n;i++){
            cin>>len[i];
            for(int j=1;j<=len[i];j++)
                cin>>a[i][j];
        }
        dp[0][0] = 1;
        
        for(int i=1;i<=n;i++){
            for(int z=0;z<=10000;z++){
                for(int j=1;j<=len[i];j++){
                    dp[i][z] += dp[i-1][z-a[i][j]];
                }
            }
        }
        ll ans = 0;
        for(int i=1;i<=10000;i++){
            if(dp[n][i] >= k){
                ans += 1ll*k*i;
                break ;
            }else{
                ans += 1ll*dp[n][i]*i;
                k -= dp[n][i];
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    磁盘管理之磁盘组成
    用户管理
    定时任务
    虚拟机安装centos6.9
    linux的文件属性与文件权限
    linux磁盘容量不足
    正则表达式与特殊符号
    linux三剑客与正则案例
    借用父构造函数继承属性
    myeclipse常用快捷键
  • 原文地址:https://www.cnblogs.com/QFNU-ACM/p/12640491.html
Copyright © 2011-2022 走看看