题目链接:http://codeforces.com/contest/724/problem/E

题目大意:

有n个城市,每个城市有pi件商品,最多能出售si件商品,对于任意一队城市i,j,其中i<j,可以从城市i往j运输最多c件商品。 求最多一共能卖出多少件商品。  n<=10000

解法一(官方解法):

构造网络流,因为边太多,不可能直接跑最大流。 根据图的特殊性,考虑用dp求解最小割。

状态:dp[i,j]表示前i个中有j个和源点相通的最小割。

转移:如果第i个点不和源点相连,那么pi这条边一定要割掉,并且之前和源点相连的j个点,每个点会有一条边连向第i个点,这些边也要割掉。 花费是dp[i-1][j]+p[i]+j*c;

如果第i个点和源点相连,那么si这条边肯定要割掉。 花费是dp[i-1][j-1]+s[i];

故dp[i][j]=min(dp[i-1][j]+p[i]+j*c,dp[i-1][j-1]+s[i])。

最后答案就是min(dp[n][0...n])  时间复杂度O(n2)

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdlib>
#include <set>
using namespace std; #define X first
#define Y second
#define Mod 1000000007
#define N 10010
#define M 400010
typedef long long ll;
typedef pair<int,int> pii; int n,c;
int s[N],p[N];
ll dp[][N]; int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout); scanf("%d%d",&n,&c);
for (int i=;i<=n;i++) scanf("%d",&p[i]);
for (int i=;i<=n;i++) scanf("%d",&s[i]); int op=;
for (int j=;j<=n;j++) dp[op][j]=1e18;
for (int i=;i<=n;i++)
{
op^=;
for (int j=;j<=n;j++)
{
if (j) dp[op][j]=min(dp[op^][j-]+s[i],dp[op^][j]+1ll*j*c+p[i]);
else dp[op][j]=dp[op^][j]+p[i];
//cout<<i<<" "<<j<<" "<<dp[op][j]<<endl;
}
}
ll ans=1e18;
for (int j=;j<=n;j++) ans=min(ans,dp[op][j]);
printf("%I64d\n",ans); return ;
}

解法二:

同样是求最小割。但是利用了贪心的策略。分别求出有i个点和源点相连的 最小割。

假设已经有k-1个点与源点相连,现在要增加第k个点p。

1.对于这k-1个点中编号比p小的,假设有s个,在加入p之前,它们连到p的边肯定已经被割掉了,否则p也与源点相连。 如果加入p,那么这些边就没必要割掉了,从当前代价里减去。

2.对于这k-1个点中编号比p大的,假设有t个,在加入p之后,p连到它们的边是没有必要去割的。

3.对于编号比p大而且不在这k-1个点中的, p连到它们的边必须割去,否则它们也会与源点相连。

根据2,3     需要新割掉n-p-t条边,代价增加(n-p-t)*c;   根据1  代价减少s*c;

总的割边数变化是(n-p-t-s) =  n-p-(s+t) =  n-p-(k-1)= (n-p+1)-k.

把这个代价分为2个部分,一部分是n-p+1, 只和加入的点的编号有关 。一部分是-k,只和目前加入了几个点有关。

因此就可以贪心,每次选择n-p+1最小的点加入。

用一个multiset或者heap来维护最小值,时间复杂度O(nlogn)

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdlib>
#include <set>
using namespace std; #define X first
#define Y second
#define Mod 1000000007
#define N 10010
#define M 400010
typedef long long ll;
typedef pair<int,int> pii; int n,c;
int p[N],s[N];
multiset<ll> st; int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout); ll ans,sum=;
scanf("%d%d",&n,&c);
for (int i=;i<=n;i++) scanf("%d",&p[i]),sum+=p[i];
for (int i=;i<=n;i++) scanf("%d",&s[i]),st.insert(s[i]-p[i]+1ll*(n+-i)*c); ans=sum;
for (int i=;i<=n;i++)
{
sum+= *st.begin()-1ll*i*c;
st.erase(st.begin());
ans=min(ans,sum);
}
printf("%I64d\n",ans); return ;
}

Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E. Goods transportation (非官方贪心解法)的更多相关文章

  1. CF Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)

    1. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B. Batch Sort    暴力枚举,水 1.题意:n*m的数组, ...

  2. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)D Dense Subsequence

    传送门:D Dense Subsequence 题意:输入一个m,然后输入一个字符串,从字符串中取出一些字符组成一个串,要求满足:在任意长度为m的区间内都至少有一个字符被取到,找出所有可能性中字典序最 ...

  3. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B. Batch Sort

    链接 题意:输入n,m,表示一个n行m列的矩阵,每一行数字都是1-m,顺序可能是乱的,每一行可以交换任意2个数的位置,并且可以交换任意2列的所有数 问是否可以使每一行严格递增 思路:暴力枚举所有可能的 ...

  4. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) C. Ray Tracing

    我不告诉你这个链接是什么 分析:模拟可以过,但是好烦啊..不会写.还有一个扩展欧几里得的方法,见下: 假设光线没有反射,而是对应的感应器镜面对称了一下的话 左下角红色的地方是原始的的方格,剩下的三个格 ...

  5. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) C.Ray Tracing (模拟或扩展欧几里得)

    http://codeforces.com/contest/724/problem/C 题目大意: 在一个n*m的盒子里,从(0,0)射出一条每秒位移为(1,1)的射线,遵从反射定律,给出k个点,求射 ...

  6. Codeforces Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) A. Checking the Calendar(水题)

    传送门 Description You are given names of two days of the week. Please, determine whether it is possibl ...

  7. Codeforces Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B. Batch Sort(暴力)

    传送门 Description You are given a table consisting of n rows and m columns. Numbers in each row form a ...

  8. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B

    Description You are given a table consisting of n rows and m columns. Numbers in each row form a per ...

  9. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) A

    Description You are given names of two days of the week. Please, determine whether it is possible th ...

随机推荐

  1. FPGA重要设计思想

    FPGA重要设计思想   1.速度和面积互换原则.以面积换速度可以实现很高的数据吞吐率,其实串/并转换.就是一种以面积换速度的思想 2.乒乓操作. 3.串/并转换的思想. 高速数据处理的重要技巧之一. ...

  2. 关于js的闭包

    http://kb.cnblogs.com/page/110782/ http://www.cnblogs.com/xiaotie/archive/2011/08/03/2126145.html

  3. Generate Time Data(财务日期主数据)

        1. Generate the master data from the specific time frame that you are interested in根据你输入的时间段来产生主 ...

  4. 浅谈html5及其新特性

    什么是 HTML5? HTML5 将成为 HTML.XHTML 以及 HTML DOM 的新标准. HTML 的上一个版本诞生于 1999 年.自从那以后,Web 世界已经经历了巨变. HTML5 仍 ...

  5. WordPress 插件推荐

    1.电商类: Woocommerce 2.幻灯片: Reslider 3.网页编写类: js_composer

  6. HTTP协议的报文结构

    HTTP 有两类报文: (1) 请求报文----从客户向服务器发送请求报文,见图6-12(a). (2) 响应报文----从服务器到客户的回答,见图6-12(b). 由于 HTTP是面向文本的(tex ...

  7. 程序设计入门——C语言 第6周编程练习 1 分解质因数(5分)

    1 分解质因数(5分) 题目内容: 每个非素数(合数)都可以写成几个素数(也可称为质数)相乘的形式,这几个素数就都叫做这个合数的质因数.比如,6可以被分解为2x3,而24可以被分解为2x2x2x3. ...

  8. angularjs的$on、$emit、$broadcast

    如何在作用域之间通信呢? 1.创建一个单例服务,然后通过这个服务处理所有子作用域的通信. 2.通过作用域中的事件处理通信.但是这种方法有一些限制:例如,你并不能广泛的将事件传播到所有监控的作用域中.你 ...

  9. SQLServer字符操作

    1.CHARINDEX('A',‘VALUE’)    result:2 style:PATINDEX(varchar,varchar) 解释:A在字符串VALUE的位置次序. 2.PATINDEX( ...

  10. Android N preview 试用

    一.下载更新包 下载地址:https://developer.android.com/intl/zh-cn/preview/download.html 注意下载适合你手机的安装包哦 二.把你手机的oe ...