分析:假设dp[i]为购买前i种珍珠花费的最小价格,我们可以得到dp转移方程,\(dp[i] = min\{(cnt[i] - cnt[k] + 10) * p[i] + dp[k]\}(1 <= k < i)\),我们可以对方程式进行变形,\(dp[k] = p[i] * cnt[k] + dp[i] - cnt[i] * p[i] + 10 * p[i]\),假设\(dp[k]为y\)\(cnt[k]为x\)\(截距(dp[i] - cnt[i] * p[i] + 10 * p[i])为b\),那么我们可以得到\(y = p[i] * x + b\),那么斜率则为\(p[i]\),之后我们再用一般的凸包优化即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;
const int N = 105;
int a[N], p[N];
int dp[N];
int q[N];
int cnt[N];
int main()
{
	int t;
	scanf("%d", &t);

	while (t--)
	{
		int c;
		scanf("%d", &c);

		for (int i = 1; i <= c; ++i)
		{
			scanf("%d%d", &a[i], &p[i]);
		}

		for (int i = 1; i <= c; ++i) cnt[i] = cnt[i - 1] + a[i];

		int hh = 0, tt = 0;
		q[0] = 0;
		for (int i = 1; i <= c; ++i)
		{
			while (hh < tt && (dp[q[hh + 1]] - dp[q[hh]]) <= p[i] * (cnt[q[hh + 1]] - cnt[q[hh]])) ++hh;
			int k = q[hh];
			dp[i] = (cnt[i] - cnt[k] + 10) * p[i] + dp[k];
			while (hh < tt && (dp[q[tt]] - dp[q[tt - 1]]) * (cnt[i] - cnt[q[tt]]) >= (dp[i] - dp[q[tt]]) * (cnt[q[tt]] - cnt[q[tt - 1]])) --tt;
			q[++tt] = i;
		}

		printf("%d\n", dp[c]);
	}



	return 0;
}