B-打怪(easy)_第二十届同济大学程序设计竞赛(同步赛) (nowcoder.com)
罗列了一堆数据,但是没能找到一个合适的规律(或许算找到了,没能总结出一个公式)
由于B和C不同测试数据只有1e3
干脆直接dp暴力解决了
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
#define endl '\n'
int N, M, K, AD, HP, ans1, ans2;
int dp[maxn][maxn];//升级到攻击i 防御j的最少扣血状态
int solve()
{
int ans = INT_MAX;
for (int i = 1; i <= HP; i++)
{
for (int j = 0; j <= AD; j++)
{
if (i == 1 && j == 0)dp[1][0] = 0;
else if (i == 1)
{//只升级防御
int num = HP - 1;
int hurt = AD - (j - 1);
hurt = max(hurt, 0);
dp[1][j] = dp[1][j - 1] + num * hurt;
}
else if (j == 0)
{//只升攻击
int num = ceil(double(HP) / double(i - 1)) - 1;
int hurt = AD;
hurt = max(hurt, 0);
dp[i][0] = dp[i - 1][0] + num * hurt;
}
else
{
int num1 = ceil(double(HP) / double(i - 1)) - 1;
int hurt1 = (AD - j);
hurt1 = max(0, hurt1);
int num2 = ceil(double(HP) / double(i)) - 1;
int hurt2 = (AD - (j - 1));
hurt2 = max(hurt2, 0);
dp[i][j] = min(dp[i - 1][j] + num1 * hurt1, dp[i][j - 1] + num2 * hurt2);
}
}
}
for (int j = 0; j <= AD; j++)//攻击满的情况
ans = min(ans, dp[HP][j]);
for (int i = 1; i <= HP; i++)//防御满的情况
ans = min(ans, dp[i][AD]);
return ans;
}
int main()
{
cin >> AD >> HP;
cout << solve() << endl;
return 0;
}