题目链接: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. dom4j的quickstart

    我所理解的dom4j就是用来解析XML文档的,XML文档的重要性不言而喻,用过框架的人谁不知道呢,是不是.但是实际上需要我们自己来解析XML文档的应用场景感觉不是很多,毕竟该解析的XML都已经被框架很 ...

  2. xcode相关配置

    Xcode将全部供应配置文件(包括用户手动下载安装的和Xcode自动创建的Team Provisioning Profile)放在目录~/Library/MobileDevice/Provisioni ...

  3. Bean熟悉替换,只替换部分属性,其他属性值不改变

    Bean熟悉替换,只替换部分属性,其他属性值不改变 需要加入:asm.jar  cglib-2.1.jar,用来map和bean之间的转换(比spring和反射的效率好,因为加入了缓存) packag ...

  4. LINQ之路 8: 解释查询(Interpreted Queries)

    LINQ提供了两个平行的架构:针对本地对象集合的本地查询(local queries),以及针对远程数据源的解释查询(Interpreted queries). 在讨论LINQ to SQL等具体技术 ...

  5. 使用扫描二维码打开app

    应该不少人遇到过这种需求,扫描二维码打开app如果用户没有这个app则提示它跳转. 用网页直接来调用app是不打可能的,必须原生那边先做一些配置. 首先,安卓和苹果的调用方法是不同的. 所以我们需要先 ...

  6. 用FireFox火狐浏览器的3D Tilt 插件查看网页3D视图效果

    逛博客发现了网页的3D视图效果,一搜原来是Firefox特有的一个功能,先看效果: 相当炫酷,接下来介绍如何实现. 1.首先安装3d tilt 插件: 从火狐浏览器的添加插件页面,搜索:3D Tilt ...

  7. stm32定时器中断类型分析

    一直在用的stm32定时器的中断都是TIM_IT_Update更新中断,也没问为什么,直到碰到有人使用TIM_IT_CC1中断,才想到这定时器的中断类型究竟有什么区别,都怪当时学习stm32的时候不够 ...

  8. native vlan(本征VLAN)

    其实就是不打tag的VLAN,因为你想,一个VLAN在经过交换设备老是打tag,然后再脱掉tag...这个很浪费计算资源,尤其是在转发的报文量相当大的时候. 如何解决:     可以定义一种vlan, ...

  9. 数据库 MySQL安装图解

    MySQL安装图解 一.MYSQL的安装 1.打开下载的mysql安装文件,双击运行mysql-5.5.40-win32.msi. 2.选择安装类型,有"Typical(默认)". ...

  10. spring框架学习(四)自动装配

    set注入和构造注入有时在做配置时比较麻烦.所以框架为了提高开发效率,提供自动装配功能,简化配置.spring框架式默认不支持自动装配的,要想使用自动装配需要修改spring配置文件中<bean ...