POJ 2393 Yogurt factory

http://poj.org/problem?id=2393

贪心策略很简单 

设第i周的酸奶在 第j周做(j <= i) 那么所花的钱是 m = (i-j)*s*y_i + (c_j * y_i)

所以即求m的最小值

化简得 m = ( (i-j)*s+c_j ) * y_i

也就是求(i-j)*s+c_j的最小值  如果直接循环 穷举求(i-j)*s+c_j的最小值 O(N^2) 会超时

这里需要一点技巧 用dp的思想 

for (int i = 1; i < n; i++)
{
ci[i] = min(ci[i-1]+s, ci[i]);
}

//即 前一个选择 对后面的选择 是有保存 影响的 这样O(n)即找出了第i周的酸奶 应该在第几周做

 1 #include <iostream>
 2 #include <fstream>
 3 #include <stdio.h>
 4 #include <string.h>
 5 
 6 using namespace std;
 7 
 8 typedef long long ll;
 9 
10 int n, s, t[10004];
11 ll sum[10004], yi[10004], ci[10004];
12 
13 int main()
14 {
15     freopen("in.txt", "r", stdin);
16     while (~scanf("%d%d", &n, &s))
17     {
18         for (int i = 0; i < n; i++)
19         {
20             scanf("%d%d", &ci[i], &yi[i]);
21             //sum[i] = ci[i]*yi[i];
22         }
23     }
24     for (int i = 1; i < n; i++)
25     {
26         ci[i] = min(ci[i-1]+s, ci[i]);//dp的思想, (i-j)*s+c[j] -> ci[j] 就是求最小的ci 这种dp写法是O(n) 而之前的是O(N^2)
27     }
28     ll ans = 0;
29     for (int i = 0; i < n; i++)
30     {
31         ans += ci[i] * yi[i];
32        //ans += sum[i];
33     }
34     printf("%lld
", ans);
35     return 0;
36 }
原文地址:https://www.cnblogs.com/oscar-cnblogs/p/6360254.html