7-4
貪欲な大きな口(15点)とても貪欲な大きな口があり、小さなケーキを食べるのが好きで、小さなケーキはどれも美味しく、大きな口はとても傲慢です。おいしい小さなケーキを食べるには必見です。ちょうどmで、大きな口がとても怠惰なので、彼女は小さなケーキを最小限に食べることでこの目標を達成したいと考えています。したがって、彼女は、どの小さなケーキを食べるかを決めるのに役立つプログラムを設計できることを望んでいます。
入力形式:
最初に2つの整数mとnを含む行を入力します。これは、大きな口が美味しくてmの小さなケーキを食べる必要があることを意味し、n種類の小さなケーキがあります。以下にn行を入力し、各行に2つの整数を入力します。 1つ目はこの種の小さなケーキの美味しさを示し、2つ目はケーキショップでのこの種の小さなケーキの総数を示します
出力形式:
出力行には、Big Mouthが食べる必要のある小さなケーキの最小数を示す整数が含まれています。BigMouthが小さなケーキを食べても美味しさの合計に達しない場合は、 "> <"を出力します。
入力サンプル:これ
が入力のセットです。例えば:
10 2
4 1
2 10
出力サンプル:
対応する出力は次のとおりです。例えば:
4
入力例:入力
のセットをここに示します。例えば:
10 2
4 1
7 3
出力サンプル:
対応する出力は次のとおりです。例えば:
<
解決策:これは複数のナップザックの問題です。
2つの解決策
最初の解決策
はdpで表されます。これは、美味しさがiのときに食べられるケーキの最小量です。
その場合、彼の伝達方程式は次のようになります。dp[k] = min(dp [k]、dp [kv [i]] + 1);
ケーキの種類の数、各種類の数を表す合計3つのサイクルがあります。ケーキとそれに対応する美味しさある程度に食べられるケーキの数が最も少ない。
コードは次のように表示されます。
#include <bits/stdc++.h>
#include <algorithm>
#include<iostream>
#include <stdio.h>
#define INF 0x3f3f3f3f
const int maxn=500005;
using namespace std;
typedef long long ll;
int dp[maxn];
int a[maxn];
int v[maxn];
int main(){
int m,n,t,va;
cin>>m>>n;
memset(dp,INF,sizeof(dp));
for(int i=1;i<=n;i++){
cin>>va>>t;
//dp[va]=1;
/*
for(int k=1;k<=t;k++){
a[s+k]=v;
}
s+=t;*/
v[i]=va;
a[i]=t;
}
//cout<<s<<endl;;
dp[0]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=a[i];j++){
for(int k=m;k>=v[i];k--){
if(k-v[i]>=0){
//dp[i-a[j]*k]=k;
dp[k]=min(dp[k],dp[k-v[i]]+1);
}
//if(k-a[i]==0)
//f=1;
//cout<<"i="<<k<<"dp[i]="<<dp[k]<<endl;
}
}
}
if(dp[m]!=INF)
cout<<dp[m]<<endl;
else
cout<<"><"<<endl;
return 0;
}
2番目の方法:この複数のバックパックを通常の0-1バックパックに変換します。同じタイプのバックパックが複数ある場合は、同じタイプのケーキを1つずつ取り出すだけで、この時点でのモデルは1つになります。最も単純な0-1バックパックの。
コード
#include <bits/stdc++.h>
#include <algorithm>
#include<iostream>
#include <stdio.h>
#define INF 0x3f3f3f3f
const int maxn=500005;
using namespace std;
typedef long long ll;
int dp[maxn];
int a[maxn];
int v[maxn];
int main(){
int m,n,t,va;
cin>>m>>n;
memset(dp,INF,sizeof(dp));
int s=0;
for(int i=1;i<=n;i++){
cin>>va>>t;
//dp[va]=1;
for(int k=1;k<=t;k++){
a[s+k]=va;
}
s+=t;
}
//cout<<s<<endl;
dp[0]=0;
for(int i=1;i<=s;i++){
for(int j=m;j>=a[i];j--){
dp[j]=min(dp[j],dp[j-a[i]]+1);
}
}
if(dp[m]!=INF)
cout<<dp[m]<<endl;
else
cout<<"><"<<endl;
return 0;
}