効果の対象:
P-ドルで始まる、ショップn個の項目がありますが、1つだけにお金の支払いは、あなたがお金だけのその部分の一部をK、とまで購入することができ頼ま支払った最も高価なを購入することができますするたびに購入することができます数(K <= N <= 2E5 )
まず、私たちは、明確にする必要がありますが、この1商品を購入した場合、花を買うために少ないお金になりますので、あなたは、すべての商品は、この製品の価格よりも低く購入する必要がありますこの方法が最適です。
溶液1:
DPソリューションとこの問題のバックパックは、ソートまず、状態のいずれか前者から転送された、または最初のk個の要素から転送されたもの、最も直感的でなければならない、即ちDP [I] =分(DP [I-1 ] + [I]、DP
[IK] + [I]) 、その後、私たちはただその一つ前に過ごす<= p個の十分を買うためにお金を見つけます。
1の#include <iostreamの>
2の#include <アルゴリズム>
3 使用して 名前空間をSTD。
4 CONST INT N = 2E5 + 5 。
5 int型、T、N、P、K、ANS、[N]、DP [N]。
6 INT メイン()
7 {
8つの IOS :: sync_with_stdio(偽)。
9 cinを>> トン。
10 一方(t-- )
11 {
12 CIN >> N >> P >> K。
13 のために(INT I = 1; I <= N。I ++ )
14 CIN >> [i]は、
15 ソート(+ 1、+ N + 1 )。
16の ANS = 0 。
17 のために(INT iは= 1 ; iが<= N; I ++ )
18 {
19 DP [I] = DP [I - 1 ] + [I]。
20 もし(I> = K)
21 DP [I] =分(DP [I]、DP [I - K] + [I])。
22 であれば(DP [I] <= P)
23 ANS =MAX(ANS、I);
24 }
25 COUT << ANS << ' \ n ' 。
26 }
27 リターン 0 。
28 }
// 93ms
対処方法2:
実際には、多くの人は、ほとんどが、我々は簡単に第二のスキルが使用できなくなった時点で2次スキルは、常に我々は低価格を購入する前に持っているお金の残りの部分最高ではありません使用しようと、貪欲見つけることができていると思うようになりましたA。私達はちょうどそう、K-1を列挙シングル買い(> = K、そして、私たちはいくつかのより多くの費用対効果を購入するために第2のスキルを使用します)の前に、ライン上の我々はすべての買い秒スキルと後者には、メンテナンスの数を購入することができます最大の罰金。
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 const int N = 2e5 + 5; 5 int t, n, p, k, a[N]; 6 int main() 7 { 8 ios::sync_with_stdio(false); 9 cin >> t; 10 while (t--) 11 { 12 cin >> n >> p >> k; 13 for (int i = 0; i < n; i++) 14 cin >> a[i]; 15 sort(a, a + n); 16 int now = 0, pre = 0, ans = 0, cnt = 0; 17 for (int i = 0; i < k; i++) 18 { 19 now = pre; 20 cnt = i; // 单买前 cnt 个商品,目前花费 now 元 21 if (now > p) 22 break; 23 for (int j = i + k - 1; j < n; j += k) // 第 i 件之后的全部用二技能买 24 { 25 now += a[j]; 26 if (now <= p) 27 cnt += k; 28 else 29 break; 30 } 31 ans = max(ans, cnt); 32 pre += a[i]; 33 } 34 cout << ans << '\n'; 35 } 36 return 0; 37 }
// 108ms