POJ 2393 Yogurt factory~贪心详解

这道题题意为酸奶厂要生产N周的酸奶,第i周生产每单位的牛奶需要c_i元,需要y_i单位的牛奶。酸奶厂有一个仓库,仓库储存费为每周每单位的牛奶需要花费S元。求生产牛奶的最少花费。

一开始做这道题,思路是开一个二维数组,第i行记录从第0周一直到第i周生产y_i单位牛奶所需费用,然后再找出最小值来加。这个方法是特别笨的一个方法,既超时又超内存,说多都是泪啊···不过经过修改把内存降下来了,二维数组变成一维,省去了很多不必要的内存空间。而TLE没有解决。

然后看别人的讨论,看到了:

*mincost[i]为刚好通过i周的最小花费,mincost[i]=mincost[i-1]+produce[i][y[i]];
produce[i][y[i]]表示前i周生产y[i]单位酸奶并存储到第i周所需的最小花费
produce[i][y[i]]一定是从某一个周生产的;设为j周,produce[i][y[i]]=w[j]*y[i]+s*(i-j)*y[i]=y[i]*(w[j]+s*(i-j));
即问题在于寻找最小的(w[j]+s*(i-j))
发现这个式子与当前所在的周数无关(任取两周a,b.发现a优于b的不等式的成立与i无关),所以就比较之前最优的周和当前周就可以了

于是再度修改函数,终于把一层for循环也去掉了,复杂度变为O(n),一试果真通过啦~

贴上代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,s;
long long b[10001];
int a[10001][2];
int vis;
long long sum;
void pre(int x)
{
	int i;
	long long temp=a[x][0]*a[x][1];
	
	if(temp>a[vis][0]*a[x][1]+s*a[x][1]*(x-vis))
	{
		temp=a[vis][0]*a[x][1]+s*a[x][1]*(x-vis);
	}
	else
	vis=x;//记录最优周
	
	b[x]=temp;
}
int main(void)
{
	int i,j;
	while(scanf("%d%d",&n,&s)!=EOF)
	{
		for(i=0;i<n;i++)
		for(j=0;j<2;j++)
		cin>>a[i][j];
				
		sum=0;
		vis=0;
		sum+=a[0][0]*a[0][1];
		
		for(i=1;i<n;i++)
		pre(i);
		
		for(i=1;i<n;i++)
		sum+=b[i];
		
		cout<<sum<<endl;
	}
	return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值