您的位置:首页 > 编程语言 > Go语言

Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E. Goods transportation (非官方贪心解法)

2016-11-20 23:41 573 查看
题目链接: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
[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 p
,s
;
multiset<ll> st;

int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);

ll ans,sum=0;
scanf("%d%d",&n,&c);
for (int i=1;i<=n;i++) scanf("%d",&p[i]),sum+=p[i];
for (int i=1;i<=n;i++) scanf("%d",&s[i]),st.insert(s[i]-p[i]+1ll*(n+1-i)*c);

ans=sum;
for (int i=1;i<=n;i++)
{
sum+= *st.begin()-1ll*i*c;
st.erase(st.begin());
ans=min(ans,sum);
}
printf("%I64d\n",ans);

return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐