トピックリンク
アイデア:
このトピックではバックパックの容量が大きすぎるため、タイムアウトの問題はもちろん、dpアレイも開くことができないため、バックパックの容量を減らす方法を見つける必要があります。そうすれば、貪欲を考えることができます。
まず、3つのリンゴを最大から最小の密度で並べ替えてから、小さいスペースと大きいスペースの2つのスペースに分割します。大きいスペースは、最も密度の高いスペースで直接埋められます(おそらく左スペースの一部、残りのスペースは自動的に小さいスペースに割り当てられます)、小さい部分は完全にバックパックされます。
これにより、バックパックの容量が過剰になる問題が解決されます。ただし、貪欲を使用する場合は、このままにしておいてください。小さなスペースの一部は小さすぎてはいけません。
例:
リンゴ3個。
4 7
3 5
6 2
容量 6
もちろん、残りのスペースの量は考慮していません。最も密度の高いリンゴを取り込めなくなるまで取り、残りのスペースをバックパッキングに使用します。
明らかに、7の価値がある最初のリンゴ
を取りますが、明らかに2番目のリンゴを2回取ります。これはより価値があります。ですから、やみくもに貪欲は間違いを犯します。完全なバックパッキングに適したスペースを見つける必要がありますが、小さい部分の取り方を尋ねられます。現時点では、推測(顔を覆う)しか言えません。理論的には、大きいほど良いです。 、しかし時間の複雑さを考慮して、私は1000を取りました
コード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxc = 1e4 + 5;
const int maxn = 4;
struct Apple
{
int val,weight;
double p;//密度
bool operator < (const Apple &a) const
{
return p > a.p;
}
}apple[maxn];
int dp[maxc];
int main()
{
ios::sync_with_stdio(false);
int t,k = 0;
cin>>t;
while(t--){
memset(dp,0,sizeof dp);
k++;
for(int i = 1; i <= 3; i++){
cin>>apple[i].weight>>apple[i].val;
apple[i].p = 1.0 * apple[i].val / apple[i].weight;
}
sort(apple + 1,apple + 4);
ll bag,ans = 0;
cin>>bag;
if(bag > 1000) ans = (bag - 1000) / apple[1].weight * apple[1].val,bag = 1000 + (bag - 1000) % apple[1].weight;
for(int i = 1; i <= 3; i++){
for(int j = apple[i].weight; j <= bag; j++){
dp[j] = max(dp[j],dp[j - apple[i].weight] + apple[i].val);
}
}
ans = ans + dp[bag];
cout<<"Case "<<k<<": "<<ans<<endl;
}
return 0;
}