Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E. Goods transportation (非官方贪心解法)
题目链接: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 (非官方贪心解法)的更多相关文章
- 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的数组, ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)D Dense Subsequence
传送门:D Dense Subsequence 题意:输入一个m,然后输入一个字符串,从字符串中取出一些字符组成一个串,要求满足:在任意长度为m的区间内都至少有一个字符被取到,找出所有可能性中字典序最 ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B. Batch Sort
链接 题意:输入n,m,表示一个n行m列的矩阵,每一行数字都是1-m,顺序可能是乱的,每一行可以交换任意2个数的位置,并且可以交换任意2列的所有数 问是否可以使每一行严格递增 思路:暴力枚举所有可能的 ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) C. Ray Tracing
我不告诉你这个链接是什么 分析:模拟可以过,但是好烦啊..不会写.还有一个扩展欧几里得的方法,见下: 假设光线没有反射,而是对应的感应器镜面对称了一下的话 左下角红色的地方是原始的的方格,剩下的三个格 ...
- 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个点,求射 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- centos 6.4 升级python到版本2.7.12
注意:需要root权限 查看python版本:python --version 1.下载Python-2.7.12wget https://www.python.org/ftp/python/2.7. ...
- JavaScript继承
最佳的继承范式 寄生组合继承 我们来看一下它的实现方式: function Object(o){ var TempObject = function(){}; TempObject.prototype ...
- IE11 HTML Help ActiveX
<!--by: @qab--> <OBJECT id=HHCTRL type="application/x-oleobject" classid="cl ...
- HANA SQL
约束 注释 你可以给你的 SQL 语句添加注释来增加可读性和可维护性. SQL 语句中注释的分隔如下: l 双连字符“--”.所有在双连字符之后直到行尾的内容都被 SQL 解析器认为是注释. l ...
- 谈谈Web前端工程师的定位
原文地址:http://www.360doc.com/content/10/0708/17/1277406_37692580.shtml 2010-07-08 锋子chans 阅 1116 转 ...
- java简单计算器
写的一个小计算器,留着以后看吧. import java.awt.BorderLayout; import java.awt.Button; import java.awt.Color; import ...
- jQuery.hasClass() 函数
hasClass() 函数 判断当前选择元素是否有指定的类名 语法 $(selector).hasclass(classname) 返回值 返回值为布尔型(true/false) 如果当前选择对象包含 ...
- iOS - MKMapView 地图
1.创建 MKMapView 地图 在 iOS6 或者 iOS7 中实现这个功能只需要添加地图控件.设置用户跟踪模式.在 mapView:didUpdateUserLocation: 代理方法中设置地 ...
- leveldb 学习。
1)大概浏览了leveldb文档的介绍.本想逐步看代码,想想还是自己先实现一个看看如何改进. 2)完成了一个非常丑陋的初版,但是还是比初初版有进步. 3)key value的数据库,不允许有key重复 ...
- 基础笔记12(socket,url网络通信)
进一步深入socket 1.网络通信条件: .IP地址,可用主机名. .传输数据时将不用的应用程序通过数字标识区分开来,这种标识称为逻辑端口,也称端口.(0-65535端口,一般系统预留0-1024) ...