【题目链接】 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2266

【题目大意】

  有M个桶,N个球,球编号为1到N,每个球都有重量w_i。
  给出一个长K的数列,数列由球的编号构成。开始的时候,桶都是空的。
  接着我们从前往后从数列中取出一个数a_j,执行如下操作:
  如果球a_j已经存在于某一个桶中,那么什么也不干,花费为0,继续。
  如果任何桶中都没有a_j,那么找一个桶放a_j,
  如果该桶里还有球,那么取出原来的球,将a_j放进去。
  这种操作的花费是a_j的重量w_a_j,与桶以及原来的球没关系。
  求最小花费?

【题解】

  我们先假设我们只有一个桶,那么答案就是权值总和,
  然后我们考虑一下如何节省开支,多出来的m-1个桶可以让我们保留一些序号
  一直到下一个相同序号,就节省下了这个序号的费用,
  那这样,我们就得到了这个桶在这个时间区段,被这个序号所占用的信息
  我们将每个桶需要保留到下一个相同需要需要的时间区段整理成一个线段集合,
  那我们只要求出这些线段在最多相交m-1次的情况下能够得到的最大权值和,
  就是我们可以节省的最大开支了。

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
using namespace std;
const int INF=0x3f3f3f3f;
typedef long long LL;
struct edge{
int to,cap,cost,rev;
edge(int to,int cap,int cost,int rev):to(to),cap(cap),cost(cost),rev(rev){}
};
const int MAX_V=10010;
int V,dist[MAX_V],prevv[MAX_V],preve[MAX_V];
vector<edge> G[MAX_V];
void add_edge(int from,int to,int cap,int cost){
G[from].push_back(edge(to,cap,cost,G[to].size()));
G[to].push_back(edge(from,0,-cost,G[from].size()-1));
}
int min_cost_flow(int s,int t,int f){
int res=0;
while(f>0){
fill(dist,dist+V,INF);
dist[s]=0;
bool update=1;
while(update){
update=0;
for(int v=0;v<V;v++){
if(dist[v]==INF)continue;
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0&&dist[e.to]>dist[v]+e.cost){
dist[e.to]=dist[v]+e.cost;
prevv[e.to]=v;
preve[e.to]=i;
update=1;
}
}
}
}
if(dist[t]==INF)return -1;
int d=f;
for(int v=t;v!=s;v=prevv[v]){
d=min(d,G[prevv[v]][preve[v]].cap);
}f-=d;
res+=d*dist[t];
for(int v=t;v!=s;v=prevv[v]){
edge &e=G[prevv[v]][preve[v]];
e.cap-=d;
G[v][e.rev].cap+=d;
}
}return res;
}
void clear(){for(int i=0;i<=V;i++)G[i].clear();}
const int MAX_N=10010;
int M,N,K,w[MAX_N],lst[MAX_N],a[MAX_N];
int solve(){
for(int i=1;i<=N;i++)scanf("%d",&w[i]);
for(int i=1;i<=K;i++)scanf("%d",&a[i]);
int cnt=unique(a+1,a+K+1)-(a+1);
int res=0;
memset(lst,0,sizeof(lst));
V=cnt+1; clear();
for(int i=1;i<=cnt;i++){
res+=w[a[i]];
if(lst[a[i]])add_edge(lst[a[i]],i-1,1,-w[a[i]]);
lst[a[i]]=i;
}for(int i=1;i<cnt;i++)add_edge(i,i+1,INF,0);
printf("%d\n",res+min_cost_flow(1,cnt,M-1));
}
int main(){
while(~scanf("%d%d%d",&M,&N,&K))solve();
return 0;
}

AOJ 2266 Cache Strategy(费用流)的更多相关文章

  1. POJ 2677 旅行商问题 双调dp或者费用流

    Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3408   Accepted: 1513 Description ...

  2. hdu-5988 Coding Contest(费用流)

    题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Ot ...

  3. POJ2195 Going Home[费用流|二分图最大权匹配]

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22088   Accepted: 11155 Desc ...

  4. BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

    3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 960  Solved: 5 ...

  5. 洛谷 1004 dp或最大费用流

    思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...

  6. Codeforces 730I [费用流]

    /* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给两行n个数,要求从第一行选取a个数,第二行选取b个数使得这些数加起来和最大. 限制条件是第一行选取了某个数的条件下,第二行不能选取对应位置的数. ...

  7. zkw费用流+当前弧优化

    zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...

  8. 【BZOJ-4213】贪吃蛇 有上下界的费用流

    4213: 贪吃蛇 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 58  Solved: 24[Submit][Status][Discuss] Desc ...

  9. 【BZOJ-3638&3272&3267&3502】k-Maximum Subsequence Sum 费用流构图 + 线段树手动增广

    3638: Cf172 k-Maximum Subsequence Sum Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 174  Solved: 9 ...

随机推荐

  1. Faster R-CNN教程

    Faster R-CNN教程 最后更新日期:2016年4月29日 本教程主要基于python版本的faster R-CNN,因为python layer的使用,这个版本会比matlab的版本速度慢10 ...

  2. codeforces902C. Hashing Trees

    https://codeforces.com/contest/902/problem/C 题意: 给你树的深度和树的每个节点的深度,问你是否有重构,如果有重构输出两个不同的结构 题解: 如果相邻节点的 ...

  3. idea设置文件的编码格式

    在打开某些类时会发现注释是乱码的,该如何解决idea的文件乱码呢?这就需要设置这个文件的合适编码格式: idea设置文件编码的两种方式分别如下: 第一种方式点击idea的右下角的图标如下图所示: 第二 ...

  4. 测试数据库DG搭建为正式库以后做准备

    Data guard 部署 1.系统准备(备库只需建立数据库软件) 两台操作系统 oracle linux 7 Node1 172.16.70.191 Node2 172.16.70.192 Orac ...

  5. eclipse 主题文件配置

    eclipse市场搜索 Eclipse Color Theme ----用于控制文本域主题 Eclipse 4 Chrome Theme  chrome风格的主题 最新的:Jeeeyul's Them ...

  6. CSS3学习笔记之立体线框球形动画

    效果截图: HTML代码: <div class="ball-box"> <div class="ball"> <div clas ...

  7. 转:Spring-session & redis 子域名共享session

    Spring-session & redis 子域名共享session 例子: a.example.com b.example.com spring 版本 4.2.6.RELEASE Spri ...

  8. bzoj 3224 裸平衡树

    裸的平衡树,可以熟悉模板用,写题写不出来的时候可以A以下缓解下心情. /************************************************************** P ...

  9. 【MT8382/8121】为MTK的工厂测试添加测试项

    摘要: 本文介绍添加MTK工厂测试项的步骤及调试技巧. 纲要: 1. 描述添加MTK工厂测试项的步骤 2.调试小技巧 1. 描述添加MTK工厂测试项的步骤 以添加红外测试为例: 1. mediatek ...

  10. (十二)Linux内核驱动之poll和select

    使用非阻塞 I/O 的应用程序常常使用 poll, select, 每个允许一个进程来决定它是否可读或者写一个或多个文件而不阻塞. 这些调用也可阻塞进程直到任何一个给定集合的文件描述符可用来读或写.  ...