比赛链接
J.铁刀磨成针
题目描述
小鸡最近沉迷于【L2】传说中的刀贼卡组,该卡组秉承开局一把刀、输出全靠砍的思想,力求对敌方造成尽可能多的伤害。
一把刀初始攻击力为
,接下来有
个回合,每回合按顺序包括以下两个阶段:
磨刀阶段:可以选择花费一单位磨刀石提升刀的攻击力一点(每回合最多一次);
攻击阶段:可以选择攻击,会对敌方造成等同于刀攻击力的伤害、并使刀的攻击力减一(每回合最多一次)。刀的攻击力归零时会损坏、此后再也不能攻击。
假设初始磨刀石的个数是
,给定
,求最大造成的伤害。
输入描述
每个测试文件均包含多组测试数据。第一行输入一个整数
代表数据组数,每组测试数据描述如下:
第一行输入三个正整数
代表回合数、初始攻击力、初始磨刀石数量。
注意本题对多个测试文件的
之和没有额外的限制。
输出描述
对于每一组测试数据,输出一行一个整数,代表最大造成的伤害。
解题思路
首先,磨刀一定是从第一回合开始一直磨,直到磨刀石用完。
其次,砍的时间也应该是连续的,中间停止砍只会让总伤害减少。
因此,只需枚举开始砍的时间点即可,如果 ,则最晚应在
时间开始砍,在此之后砍只会让总伤害减少。
完整代码
#include<bits/stdc++.h>
#define int long long
#define ll long long
using namespace std;
int n, x, y;
int dc(int a, int n) {
return a * n - n * (n - 1) / 2;
}
static void solve() {
int ans = 0;
cin >> n >> x >> y;
for (ll t = 1; t <= min(n, y); t++) { // 枚举开始时间
ll tmp = 0;
ll atk = x + t, s1 = min(n, y) - t; // s1:又磨又砍的时间
tmp += atk * s1; // 又磨又砍的伤害
tmp += dc(atk, min(atk, n - min(n, y) + 1)); // 只砍的伤害
ans = max(ans, tmp);
}
cout << ans << endl;
}
signed main() {
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}