(水)POJ-2393 贪心,生产问题

题目大意:任务规定,一个酸奶制造厂,在n个星期内,分别要向外提供y[i]unit的酸奶。已知这个制造厂第i周制造每unit酸奶的费用为c[i],储存室储存每1unit酸奶1星期的费用为s。问要完成这个任务的最小费用是多少。


题目链接:点击打开链接


分析:严格的说这题就是个简单的数学应用题。

第1周要提供的y1单位奶,肯定只能通过自己生产来满足。

第2周要提供的y2单位奶,可以由第1周生产保存下来(如果第1周生产更优则肯定全由第1周生产),也可以自己生产(全由自己生产)。若为第1周生产则需 c1*y2+(2-1)*s*y2 =(c1+s)*y2 元,若自己生产则需 c2*y2 元,最优肯定为两者Min值。

第3周要提供的y3单位奶,可以由第1周或第2周生产保存下来,也可以自己生产。若为第1周生产则需c1*y3+(3-1)*s*y3 = (c1+2*s)*y3 元,若为第2周生产则需c2*y3+(3-2)*s*y3 = (c2+s)*y3 元,自己生产则需要c3*y3 元,最优肯定为三者Min值。观察发现,如果第2周中的牛奶都由第1周生产,即 c1+s < c2 ,那么 c1+2*s < c2+s ,也就是说第3周由第1周还是由第2周来生产与第2周由谁来生产的结果一致,所以只要比较自己生产更优还是第1周更优就行了。

因此我们只要扫一遍,维护当前最优的生产周(记为v)就行了。如果c[i]<c[v]+(i-v)*s那么就自己生产并更新最优生产周,否则由第v周来生产。


附上代码:

#include<iostream>        //POJ-2393
using namespace std;
int y[10000 + 5], c[10000 + 5];
int n, s;
long long ans;    //注意long long
int main()
{
	scanf("%d%d", &n, &s);
	for (int i = 1; i <= n; i++)
		scanf("%d%d", &c[i], &y[i]);
	int v = 1;
	ans += c[1] * y[1];
	for (int i = 2; i <= n; i++)
	{
		if (c[i] < c[v] + (i - v)*s)     
		{
			ans += c[i] * y[i];
			v = i;                //更新最优生产周
		}
		else ans += (c[v] + (i - v)*s)*y[i];
	}
	printf("%lld\n", ans);
	return 0;
}


你可能感兴趣的:((水)POJ-2393 贪心,生产问题)