您的位置:首页 > 其它

POJ 2393 Yogurt factory~贪心详解

2017-08-17 00:53 447 查看
这道题题意为酸奶厂要生产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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm