zoukankan      html  css  js  c++  java
  • bzoj2424 [HAOI2010]订货 dp+单调性

    [HAOI2010]订货

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1311  Solved: 884
    [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

    HINT

     

    先写了个DP方程:f[i][j]=min(f[i][j],f[i-1][k]+d[i]*(j+u[i]-k)+m*k);(0<=j<=s,0<=k<=j+u[i])

      O(n*s^2),T的结果很明显

      优化一下,很容易发现其实f数组是具有一定的单调性的

      那么用单调队列来优化一下下

      当f[i-1][list[head]]+d[i]*(j+u[i]-list[head])+m*list[head]>f[i-1][list[head+1]]+d[i]*(j+u[i]-list[head+1])+m*list[head+1]的时候说明list[head+1]对于当前情况更优,所以head++,不过要判断一下list[head+1]是否<=j+u[i]

      其实f[i-1][list[head]]+d[i]*(j+u[i]-list[head])+m*list[head]>f[i-1][list[head+1]]+d[i]*(j+u[i]-list[head+1])+m*list[head+1]

      可以转化为f[i-1][list[head]]-(d[i]-m)*list[head]>f[i-1][list[head+1]]-(d[i]-m)*list[head+1],将其中不变的值去掉

     1 #include<cstring>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstdio>
     6 
     7 #define N 57
     8 #define M 10007
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0,f=1;char ch=getchar();
    13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    14     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 
    18 int n,m,s;
    19 int u[51],d[51];
    20 int f[51][11000];
    21 int list[11000];
    22 
    23 int main()
    24 {
    25     n=read(),m=read(),s=read();
    26     for(int i=1;i<=n;i++) u[i]=read();
    27     for(int i=1;i<=n;i++) d[i]=read();
    28     memset(f,63,sizeof(f));
    29     f[0][0]=0;
    30     for(int i=1;i<=n;i++)
    31     {
    32         int head=1,tail=s+1;
    33         for(int j=0;j<=s;j++) list[j+1]=j;
    34         for(int j=0;j<=s;j++)
    35         {
    36             while(head<=tail&&f[i-1][list[head]]-(d[i]-m)*list[head]>f[i-1][list[head+1]]-(d[i]-m)*list[head+1]&&list[head+1]<=j+u[i]) head++;
    37             int k=list[head];
    38             f[i][j]=f[i-1][k]+d[i]*(j+u[i]-k)+m*k;
    39         }
    40     }
    41     printf("%d
    ",f[n][0]);
    42 }
  • 相关阅读:
    20165211 2017-2018-2 《Java程序设计》第1周学习总结
    nginx解析漏洞
    Killable Processes in Oracle Database
    Know more about PGA_AGGREGATE_LIMIT 12c 19c
    mysql查看存储过程函数
    oracle 12.1.0.2升级oracle12.2.0.1(non cdb)
    MySQL 一张表单个索引最多支持创建16个字段
    AWR automatic or manual snapshot hangs – EXADATA
    创建表时报错,索引列超过最大约束
    mysql while 循环
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8745644.html
Copyright © 2011-2022 走看看