Final Exam(HDU-6651)
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 10Sample Output
11
1100
题意:t 组数据,每组给出 n、m、k 三个数,代表有 n 个问题,这些问题的总分为 m,对于每一道题,假设其分值为 x,那么要复习 x+1 个小时才能拿到这个题的分,问做出 k 个题的最少复习时间
思路:
题目可以理解为,有两个序列 a、b,其中 a 序列值未知,但总和为 m,b 序列要进行填数,使得至少有 k 个 b[i] 满足 b[i]=a[i]+1
序列 a 中的每一个数 a[i] 是可以在 0~m 随意设的,只要满足总和等于 m 即可,如果 a 不想让 b 赢,那么会至少让 k-1 个 0 与 b 的前 k-1 个大相比较,只需要让 b 剩下的 (n-(k-1)) 个数都小于 a 剩下的 (n-(k-1)) 个数即可
因此,a 中最大数可以取 m/(n-(k-1))+1
反之,只要让 b 中的 k-1 个数取 m/(n-(k-1))+1,为了保证最后能赢,最后一个数取 m+1,其余取 0,那么就一定会有 k 个数符合条件
这样当 a 取最优策略,a 中的 k-1 个 0 与 b 中前 k-1 大的数比较,b 就有 k-1 个数符合条件,b 中剩下的第 k 小的数一定会比 a 中剩下的某一个数大,因此就有 k 个数符合条件
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;}
LL quickPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;}
LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-10;
const int MOD = 998244353;
const int N = 1000000+5;
const int dx[] = {-1,1,0,0,1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;
int main() {
int t;
scanf("%d", &t);
while (t--) {
LL n, m, k;
scanf("%lld%lld%lld", &n, &m, &k);
LL sum = 0;
sum = (k - 1) * (m / (n - (k - 1)) + 1);
sum += (m + 1);
printf("%lld\n", sum);
}
return 0;
}