#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
//#define DEBUG
/* 244K 0MS */
static const int MAX = 101;
static int count[MAX];
static int price[MAX];
static int presum[MAX];
static int n;
static int f[MAX];
int main()
{
#ifdef DEBUG
fstream cin("G:\\book\\algorithms\\acm\\Debug\\dat.txt");
#endif
int t;
cin >> t;
while (t-- > 0)
{
cin >> n;
int i, j;
for (i = 1; i <= n; i++)
{
cin >> count[i] >> price[i];
presum[i] = presum[i - 1] + count[i];
}
f[1] = (count[1] + 10) * price[1];
for (i = 2; i <= n; i++)
{
int min = (presum[i] + 10) * price[i];
for (j = 1; j < i; j++) /* 列举全部可能性 找到最小值 */
{
int tmp = (presum[i] - presum[j] + 10) * price[i] + f[j];
if (tmp < min)
min = tmp;
}
f[i] = min;
}
printf("%d\n", f[n]);
}
return 0;
}
对于第i项,列举其全部的可能组合,进行比较找到其中的最小值,就是解。题目中的输入数据已经做了部分简化,
1.输入数据按照price的升序进行排列
2.购买时的替代是单方向的
从本质上讲这一题还是一个“划分”的变形。找到划分方法也就找到了动态转移方程。