题目描述

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

输入输出格式

输入格式:

第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)

输出格式:

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

方法一:DP

思路

读完题目,DP方程就有了 f[i][j]f[i][j]f[i][j] 表示第 iii 个月底仓库剩余 j" role="presentation" style="position: relative;">jjj 个的最优解。

显然f[i][j]=min(f[i−1][k]+(U[i]+j−k)∗d[i]+k∗m)f[i][j]=min(f[i−1][k]+(U[i]+j−k)∗d[i]+k∗m)f[i][j]=min(f[i-1][k]+(U[i]+j-k)*d[i]+k*m)

然而复杂度为 O(N∗S2)O(N∗S2)O(N*S^2)

不过,可以优化。

将式子展开。

f[i][j]=min(f[i−1][k]+U[i]∗d[i]+j∗d[i]−k∗d[i]+k∗m)f[i][j]=min(f[i−1][k]+U[i]∗d[i]+j∗d[i]−k∗d[i]+k∗m)f[i][j]=min(f[i-1][k]+U[i]*d[i]+j*d[i]-k*d[i]+k*m)

f[i][j]=min((f[i−1][k]−k∗d[i]+k∗m)+U[i]∗d[i]+j∗d[i])f[i][j]=min((f[i−1][k]−k∗d[i]+k∗m)+U[i]∗d[i]+j∗d[i])f[i][j]=min((f[i-1][k]-k*d[i]+k*m)+U[i]*d[i]+j*d[i])

观察上式,我们发现,如果可以预处理出 f[i−1][k]−k∗d[i]+k∗mf[i−1][k]−k∗d[i]+k∗mf[i-1][k]-k*d[i]+k*m 就能 O(1)O(1)O(1) 得出 f[i][j]f[i][j]f[i][j] 。

所以可以维护一个 ggg 数组,令

g[i][j]={min(f[i][j]+j∗(m−d[i+1]),g[i][j−1])(j&gt;0)f[i][j]+j∗(m−d[i+1])(j=0)" role="presentation">g[i][j]={min(f[i][j]+j∗(m−d[i+1]),g[i][j−1])f[i][j]+j∗(m−d[i+1])(j>0)(j=0)g[i][j]={min(f[i][j]+j∗(m−d[i+1]),g[i][j−1])(j>0)f[i][j]+j∗(m−d[i+1])(j=0)

g[i][j]= \begin{cases}min(f[i][j]+j*(m-d[i+1]),g[i][j-1]) & (j>0)\\f[i][j]+j*(m-d[i+1]) & (j=0) \end{cases}
即可。

代码

#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int N,M,S,U[55],d[55],f[55][10005],g[55][10005];
inline int read() {int ret=0,f=1;char ch=getchar();for (; !isdigit(ch); ch=getchar()) if (ch=='-') f=-f;for (; isdigit(ch); ch=getchar()) ret=ret*10+ch-48;return ret*f;
}
int main() {N=read(),M=read(),S=read();memset(f,0x3f,sizeof f),f[0][0]=0;for (int i=1; i<=N; i++) U[i]=read();for (int i=1; i<=N; i++) d[i]=read();for (int i=1; i<=N; i++)for (int j=0; j<=S; j++) {f[i][j]=min(f[i][j],g[i-1][min(S,j+U[i])]+U[i]*d[i]+j*d[i]);g[i][j]=f[i][j]+j*(M-d[i+1]);if (j) g[i][j]=min(g[i][j-1],g[i][j]);}printf("%d\n",f[N][0]);return 0;
}

方法二:费用流

思路

代码

#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int maxn=1e5+5,INF=0x3f3f3f3f;
deque <int> Q;
bool vis[maxn];
int N,M,C,S,T,ans,son[maxn],flw[maxn],cst[maxn],nxt[maxn],lnk[maxn],dis[maxn],tot;
inline int read() {int ret=0,f=1;char ch=getchar();for (; !isdigit(ch); ch=getchar()) if (ch=='-') f=-f;for (; isdigit(ch); ch=getchar()) ret=ret*10+ch-48;return ret*f;
}
inline void add_edge(int x,int y,int f,int c) {son[tot]=y,flw[tot]=f,cst[tot]=+c,nxt[tot]=lnk[x],lnk[x]=tot++;son[tot]=x,flw[tot]=0,cst[tot]=-c,nxt[tot]=lnk[y],lnk[y]=tot++;
}
bool spfa() {memset(vis,0,sizeof vis);memset(dis,0x3f,sizeof dis),dis[T]=0,Q.push_back(T);while (!Q.empty()) {int u=Q.front();vis[u]=0,Q.pop_front();for (register int k=lnk[u]; ~k; k=nxt[k])if (flw[k^1]&&dis[son[k]]>dis[u]-cst[k]) {dis[son[k]]=dis[u]-cst[k];if (!vis[son[k]]) {vis[son[k]]=1;if (!Q.empty()&&dis[Q.front()]>dis[son[k]]) Q.push_front(son[k]);else Q.push_back(son[k]);}}}vis[T]=1;return dis[S]<INF;
}
int dfs(int x,int flow) {vis[x]=1;if (x==T||flow==0) return flow;int cnt=0;for (register int k=lnk[x]; ~k&&flow; k=nxt[k])if (!vis[son[k]]&&flw[k]&&dis[son[k]]==dis[x]-cst[k]) {int d=dfs(son[k],min(flow,flw[k]));if (d<=0) continue;cnt+=d,flow-=d,flw[k]-=d,flw[k^1]+=d,ans+=cst[k]*d;}return cnt;
}
int main() {memset(lnk,-1,sizeof lnk);N=read(),M=read(),C=read(),S=0,T=N+1;for (int i=1; i<=N; i++) add_edge(i,T,read(),0);for (int i=1; i<=N; i++) add_edge(S,i,INF,read());for (int i=1; i<N; i++) add_edge(i,i+1,C,M);while (spfa()) while (vis[T]) memset(vis,0,sizeof vis),dfs(S,INF);printf("%d\n",ans);return 0;
}

[HAOI2010]订货 洛谷2517 BZOJ2424相关推荐

  1. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  2. 洛谷 P1142 轰炸

    洛谷 P1142 轰炸 题目描述 "我该怎么办?"飞行员klux向你求助. 事实上,klux面对的是一个很简单的问题,但是他实在太菜了. klux要想轰炸某个区域内的一些地方,它们 ...

  3. 洛谷 P1387 最大正方形

    P1387 最大正方形 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=10 ...

  4. 洛谷P2763 试题库问题

    题目:https://www.luogu.org/problemnew/show/P2763 题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性. ...

  5. 动态规划——洛谷_P1057传球游戏

    题目: 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏.游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球, ...

  6. 洛谷P1417 烹调方案

    洛谷P1417 烹调方案 如果是一般的01背包的话 选的先后是没关系的 但是这题选的先后是有关系的,因为他的价值是随着时间而变化的, 而你的01背包是做不到先选2再选1的 那么我们就跟国王游戏一样 用 ...

  7. 记忆优化搜索(简单题)(洛谷P3183 [HAOI2016]食物链 )( P5635 【CSGRound1】天下第一 )

    昨天做了蓝桥杯的时候,发现自己对于记忆优化搜索甚是不熟悉,所以今天随便找了几个基础题做做,顺便写下两片题解,顺便用了一下devc++敲的代码,发现没有代码补全真的可以说是灰常难受了... 洛谷P318 ...

  8. 洛谷 - 试炼场(全部题目备份)

    整理的算法模板合集: ACM模板 目录 1.新手村 1 - 1 洛谷的第一个任务 1 - 2 顺序与分支 1 - 3 循环!循环!循环! 1 - 4 数组 1 - 5 简单字符串 1 - 6 过程函数 ...

  9. 洛谷专题训练 ——【算法1-1】模拟与高精度

    洛谷题单[算法1-1]模拟与高精度 ACM-ICPC在线模板 题单链接: [算法1-1]模拟与高精度 下面的这一坨都是洛谷题单上的东东 题单简介 恭喜大家完成了第一部分语言入门,相信大家已经可以使用 ...

最新文章

  1. RubyGems 库发现了后门版本的网站开发工具 bootstrap-sass
  2. html请求接口_通用网关接口-FastCGI介绍
  3. SpringBoot中注入ApplicationContext对象的三种方式
  4. js原生实现过渡效果的返回顶部功能实例
  5. 自动驾驶_产品象限图_清洁机器人场景
  6. 一键修改分辨率bat_设置分辨率的批处理 | 学步园
  7. java sql语句中文乱码_PL/SQL执行语句中文乱码
  8. android 休眠流程
  9. 使用zxing生成彩色或带图片的二维码
  10. 秋招Java岗,心态大崩,今年的面试真的有必要这么卷吗?
  11. 博弈论大作战之 PART1
  12. JAVA简单计算器(简单实现两数加减乘除)
  13. directshow(directShow多个usb摄像头方案)
  14. 外文文献翻译工具,4款可供选择!
  15. 合数(数论基础概念)
  16. 前端基础之Html、CSS、JavaScript、JQuery、Ajax
  17. Shell小技巧(一百一十贰)特殊字符“\”-转义小结
  18. 云聚华为伙伴暨开发者大会GaussDB专场
  19. Win10中Pro/E鼠标滚轮不能缩放该怎么办?
  20. C++模板的底层实现

热门文章

  1. 中文语音合成,文本到语音的转换类库。只支持中文发音。识别数字发音。不支持多音字的识别。
  2. 【模型复现】逆合成预测/文本分类模型——MeGAN 快速复现
  3. android ndk-stack调试
  4. python游走代码_爬虫-案例
  5. 莲花SVN无限期试用方法
  6. Akka(7): FSM:通过状态变化来转换运算行为
  7. 关于Java使用 BigDecimal 的错误 Rounding necessary / Non-terminating decimal expansion...
  8. 微软OneNote 2003不能给便签设定提醒吗??
  9. API接口名称(item_get - 获取JD商品详情)[item_search,item_get,item_search_shop等]
  10. Java开发语言环境_java-springboot 2中的语言环境