• bzoj2424 [HAOI2010]订货


    2424: [HAOI2010]订货

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 855  Solved: 603
    [Submit][Status][Discuss]

    Description

    某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初的库存量为零,第n月月底的库存量也为零,问如何安排这n个月订购计划,才能使成本最低?每月月初订购,订购后产品立即到货,进库并供应市场,于当月被售掉则不必付存贮费。假设仓库容量为S。

    Input

    第1行:n, m, S (0<=n<=50, 0<=m<=10, 0<=S<=10000)
    第2行:U1 , U2 , ... , Ui , ... , Un (0<=Ui<=10000)
    第3行:d1 , d2 , ..., di , ... , dn (0<=di<=100)

    Output

    只有1行,一个整数,代表最低成本

    Sample Input

    3 1 1000
    2 4 8
    1 2 4

    Sample Output

    34
     
    题解
        讲道理啊看到第一眼就觉得是DP……网上一搜一大片网络流把我吓傻了,最后还是DP水过了23333
        显然如果仓库在第i天之后有j的货物最小费用为f[i,j],我们设在第i天出货之前仓库里有j的货物最小费用为g[i,j],则有f[i,j]=g[i,j+u[i]],相当于把答案平移了u[i]。然后一个显然的方程式可得的g[i,j]=min{f[i-1,k]+k*w+(j-k)*d[i]} (0<=k<=j),如果直接三重循环时间复杂度显然药丸,O(nm^2)。我们可以给他变个形,g[i,j]=min{f[i-1,k]+k*w-k*d[i]} +j*d[i](0<=k<=j),显然在min函数内的值只与k有关,设s[i,k]=f[i-1,k]+k*w-k*d[i],则只要维护0<=k<=j的s[i,k]的最小值,g[i,j]=min+j*d[i]就可以了。
        最后记得特殊处理一下超出容量的部分(求g[i,j]时j可以超出),然后数组可以滚动用,开一维就行了。
     1 /**************************************************************
     2     Problem: 2424
     3     User: 1090900715
     4     Language: Pascal
     5     Result: Accepted
     6     Time:96 ms
     7     Memory:344 kb
     8 ****************************************************************/
     9  
    10 program j01;
    11 var f:array[0..10000]of longint;
    12     g:array[0..20000]of longint;
    13     u,d:array[0..50]of longint;
    14     n,m,s,i,j,x:longint;
    15 function min(a,b:longint):longint;
    16 begin
    17   if a<b then exit(a) else exit(b);
    18 end;
    19 begin
    20   readln(n,m,s);
    21   for i:=1 to n do read(u[i]);
    22   for i:=1 to n do read(d[i]);
    23   fillchar(f,sizeof(f),$3f);
    24   f[0]:=0;
    25   for i:=1 to n do
    26   begin
    27     for j:=0 to s do f[j]:=f[j]+j*m-d[i]*j;
    28     x:=maxlongint;
    29     for j:=0 to s do
    30     begin
    31       x:=min(x,f[j]);
    32       g[j]:=x+d[i]*j;
    33     end;
    34     for j:=s+1 to s+u[i] do g[j]:=x+d[i]*j;
    35     for j:=0 to s do f[j]:=g[j+u[i]];
    36   end;
    37   writeln(f[0]);
    38 end.
    View Code
  • 相关阅读:
    《程序员修炼之道:从小工到专家》阅读笔记02
    第二阶段团队冲刺10
    第二阶段团队冲刺09
    周总结
    第二阶段团队冲刺08
    第二阶段团队冲刺07
    小A和小B和幽灵追两人(双向BFS)
    C. 真假亚瑟王(暴力)
    小A的柱状图(栈的应用,找左右边界)
    小A买彩票
  • 原文地址:https://www.cnblogs.com/oldjang/p/6129231.html
Copyright © 2020-2023  润新知