以最低的价格购买珍珠:
某一级别的珍珠价钱:(ai+10)*pi,ai和pi分别是这一级别珍珠的数量和单价;
珍珠随着级别的升高,价格增加;
某一级别的珍珠可以放在更高级别中卖出(省去附加的*10的钱),但不能与更低级别的珍珠一起卖。
a1 p1
a2 p2
a3 p3
a4 p4
...
ai pi
问题关键:
对于ai,...,ak,...aj-1,aj级别递增,若ai跟aj放在同一级卖出价格减少,则ai~aj-1都需要放在aj这一级别卖出总价格才会更少,
因为,若存在级别k<j, 将ai放在ak这个级别卖出,价钱会比放在aj这个级别更低。
因此,最终的方案是将珍珠的级别,划分成互不相交的若干段,每段以其中最高级别卖出。求最小价格的划分。
解决方案:
对于最高级别i,考虑总价格最小的方案:
设最后一个分段的起始为j,其最价格为,a1~aj-1的最小价格,加上最后一段的价格;
遍历j=0~i, 取最小值;
这里a1~aj-1的最小价格为一个相同的子问题。
某一级别的珍珠价钱:(ai+10)*pi,ai和pi分别是这一级别珍珠的数量和单价;
珍珠随着级别的升高,价格增加;
某一级别的珍珠可以放在更高级别中卖出(省去附加的*10的钱),但不能与更低级别的珍珠一起卖。
a1 p1
a2 p2
a3 p3
a4 p4
...
ai pi
问题关键:
对于ai,...,ak,...aj-1,aj级别递增,若ai跟aj放在同一级卖出价格减少,则ai~aj-1都需要放在aj这一级别卖出总价格才会更少,
因为,若存在级别k<j, 将ai放在ak这个级别卖出,价钱会比放在aj这个级别更低。
因此,最终的方案是将珍珠的级别,划分成互不相交的若干段,每段以其中最高级别卖出。求最小价格的划分。
解决方案:
对于最高级别i,考虑总价格最小的方案:
设最后一个分段的起始为j,其最价格为,a1~aj-1的最小价格,加上最后一段的价格;
遍历j=0~i, 取最小值;
这里a1~aj-1的最小价格为一个相同的子问题。
dp[i] = Min{dp[j-1], (sum(aj~ai)+10)*pi}, j = 0,...,i
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int n, c;
int a[100];
int p[100];
int suma[100];
int min[100];
cin >> n;
while (n-- > 0)
{
cin >> c;
for (int i = 0; i < c; ++i)
{
cin >> a[i] >> p[i];
if (i == 0)
{
suma[i] = a[i];
}
else
{
suma[i] = suma[i-1] + a[i];
}
}
int i = 0;
min[i] = (a[i]+10)*p[i];
int tmp;
for (i = 1; i < c; ++i)
{
min[i] = (suma[i]+10)*p[i];
for (int j = 0; j < i; ++j)
{
tmp = min[j] + (suma[i]-suma[j]+10)*p[i];
if (tmp < min[i])
{
min[i] = tmp;
}
}
}
cout << min[c-1] << endl;
}
return 0;
}