4.6問題の日常の問題の解決

三角形

知識ポイントを含みます:

  • バックパックDP

解決:

  • バックパックは、(あなたが学生のDP学ぶことを計画している場合はナップザック問題を学ばなければならない)非常に古典的な問題のDPアルゴリズムであり、我々はバックパック9つのストレスPDFファイルのグループで、具体的な私を見ることができます
  • この質問は、私たちがそれぞれの胸のためのバックパックを行うことができますが、程度であります
  • のみ列挙胸、利用可能であるが、プログラムjの数に等しい金額に胸部のそれぞれから採取された被験者、i番目のためのように提供DP [I] [j]を必要と
  • 、初期DP [0] [0] = 1 - その後、転写式[i]は[Z] + = DP [I-1] [[I] [J] Z]をDPに等しいです
  • I I胸部正面の代表的な、お金のZ Zの代表を得ることができる、j番目マネーA [i]が列挙胸のi番目の代表の[J]、DP [I] [Z]は、i番目のフロント胸に等しいとすることができますプログラムのお金のZ数
  • J範囲0〜10,000、小規模から最終列挙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;
}

おすすめ

転載: www.cnblogs.com/QFNU-ACM/p/12640491.html