HDU6651 Final Exam - 貪心法

Final Exam

Time Limit: 4000/2000 MS (Java/Others)   Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 462   Accepted Submission(s): 199

Problem Description

Final Exam is coming! Cuber QQ has now one night to prepare for tomorrow’s exam.

The exam will be a exam of problems sharing altogether m points. Cuber QQ doesn’t know about the exact distribution. Of course, different problems might have different points; in some extreme cases, some problems might worth 0 points, or all m points. Points must be integers; a problem cannot have 0.5 point.

What he knows, is that, these n problems will be about n totally different topics. For example, one could be testing your understanding of Dynamic Programming, another might be about history of China in 19th century. So he has to divide your night to prepare each of these topics separately. Also, if one problem is worth x points in tomorrow’s exam, it takes at least x+1 hours to prepare everything you need for examination. If he spends less than x+1 hours preparing, he shall fail at this problem.

Cuber QQ’s goal, strangely, is not to take as much points as possible, but to solve at least k problems no matter how the examination paper looks like, to get away from his parents’ scoldings. So he wonders how many hours at least he needs to achieve this goal.

Input

The first line of the input is an integer t (1≤t≤20 000), denoting the number of test cases.

Each test case are three space-separated integers n,m,k (0≤m≤109, 1≤k≤n≤109).

Output

For each test case, output the number of hours Cuber QQ needs.

Sample Input

2
1 10 1
10 109 10

Sample Output

11
1100

Hint

Cuber QQ should solve one problem in sample 1, so he at least prepares 11 hours when the problem one is 10 point.
Cuber QQ should solve all the ten problems in sample 2, so he at least prepares 110 hours for each problem because there may be one problem is 109 point.

 
 

題目大概意思:

給出三個整數 n,m,k(0m109,1kn109)n,m,k(0≤m≤10^9,1≤k≤n≤10^9) ,表示即將進行的考試試卷中有 nn 種不相關的知識點,總分爲 mm ,假設試卷中第 ii 種知識點的分值爲 xi(0xi,i=1nxi=m)x_i(0≤x_i,\sum_{i=1}^{n}{x_i=m}) ,則至少花費 xi+1x_i+1 的時間複習這個知識點纔可以拿到這一知識點的分數,否則無法獲得這一知識點的分數。求一個花費時間最小的複習策略 (yi)(y_i) ,使得對任意的試卷的知識點分值分配情況 (xi)(x_i) ,都可以保證拿到 kk 個知識點的分數,並輸出最小花費。

 
 

分析:

首先考慮這一問題:對於一個複習策略 (yi)(y_i) ,找到最小的能夠使得在使用策略 (yi)(y_i) 時無法獲得 kk 個知識點的分數的考試分值分配方法 (xi)(x_i) 。那麼一定是貪心地從 (yi)(y_i) 中複習時間最短的知識點開始分配分值,使得 xi=yix_i=y_i(即使得第 ii 個知識點無法獲得分數的最小分值) ,直到已經有 (nk+1)(n-k+1) 個知識點無法獲得分數爲止,剩餘的知識點都只分配 00 分值。

因此對於同樣的複習時間 yi\sum{y_i} ,應儘可能地讓 (yi)(y_i) 更加平均,纔會使得複習策略能夠應對的考試總分更大。所以複習策略 (yi)(y_i) 中元素的取值應爲 ysy_sys+1y_s+1 兩者之一。有了這個規律,就很容易構造出最優解了:

對於給定的 n,m,kn,m,k ,設:

使得複習策略失敗最少需要掛掉的知識點個數 fail=nk+1fail=n-k+1 ,再設 low=mfail,up=low+1low=\lfloor\frac{m}{fail}\rfloor,up=low+1 .

那麼 mm 可以表示爲:
m=low×cntlow+up×cntupm=low×cnt_{low}+up×cnt_{up}其中:cntup=mlow×fail, cntlow=failcntupcnt_{up}=m-low×fail,\,cnt_{low}=fail-cnt_{up}

那麼對於如下一個解:

y1=low,y2=low,,ycntlow1=low,ycntlow=up,ycntlow+1=up,,yn=upy_1=low,y_2=low,\dots,y_{cnt_{low}-1}=low,y_{cnt_{low}}=up,y_{cnt_{low+1}}=up,\dots,y_n=up

即由 (cntlow1)(cnt_{low}-1)lowlow(n(cntlow1))(n-(cnt_{low}-1))upup 組成的複習策略 (yi)(y_i) ,對於分值爲 mm 的考試是能夠保證得到 kk 個知識點的分數的。證明:

採用前文的貪心策略構造 (xi)(x_i) ,每次選取 (yi)(y_i) 中最小的複習時間,選取 failfail 次,並每次賦 xi=yix_i=y_i ,並將剩餘的 xix_i 賦爲0,則最終相當於選取了 m=xi=(cntlow1)×low+(cntup+1)×up=low×cntlow+up×cntup+1=m+1>mm'=\sum{x_i}=(cnt_{low}-1)×low+(cnt_{up}+1)×up=low×cnt_{low}+up×cnt_{up}+1=m+1>m 的分數,因此想要使這一複習策略失敗,至少需要 m+1m+1 的分數,因此這一複習策略可以應付所有分數爲 mm 的考試。而對於花費減小 11 的複習策略 (yi)(y'_i) ,即 yi=(yi)1\sum{y'_i=(\sum{y_i})-1} 的策略 ,則易證在使用同樣的貪心策略構造下,會在分數爲 mm 的考試下失敗,因此,花費減小 11 會使解不成立,則 (yi)(y_i) 即爲所求。

由於只進行了常數次運算,故算法的時間複雜度爲 O(1)O(1) .

 
 
下面貼代碼:

#include <cstdio>
using namespace std;

typedef long long ll;


int main()
{
	ll n, m, k;
	int t;
	scanf("%d", &t);

	while (t--)
	{
		scanf("%lld%lld%lld", &n, &m, &k);

		ll fail = n - k + 1;
		ll low = m / fail;
		ll up = low + 1;
		ll cnt_up = m - low * fail;
		ll cnt_low = fail - cnt_up;

		ll ans = low * (cnt_low - 1) + up * (n - (cnt_low - 1));

		printf("%lld\n", ans);
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章