【CF739E】Gosha is hunting

该博客介绍了如何运用费用流模型解决一个关于抓取神奇宝贝的问题。给定每只神奇宝贝被不同类型的球捕获的概率,以及球的库存,目标是最大化抓到神奇宝贝的期望数量。通过建立费用流网络并运行最大费用最大流算法,可以找到最优策略。代码实现中包含了最大费用最大流的详细过程和时间复杂度分析。

题目

题目链接:https://codeforces.com/problemset/problem/739/E
你要抓神奇宝贝!
现在一共有 NNN 只神奇宝贝。
你有 aaa 个『宝贝球』和 bbb 个『超级球』。
『宝贝球』抓到第 iii 只神奇宝贝的概率是 pip_ipi ,『超级球』抓到的概率则是 uiu_iui
不能往同一只神奇宝贝上使用超过一个同种的『球』,但是可以往同一只上既使用『宝贝球』又使用『超级球』(都抓到算一个)。
请合理分配每个球抓谁,使得你抓到神奇宝贝的总个数期望最大,并输出这个值。
n≤2000n\leq 2000n2000

思路

考虑建立费用流模型。首先对于宝贝球和超级球分别建立一个点,从源点连一条流量为球的数量,费用为 000 的边来限制每一个球的数量。
然后对于一个点 iii,从宝贝球的点连一条 (1,pi)(1,p_i)(1,pi) 的边,从超级球连一条 (1,ui)(1,u_i)(1,ui) 的边,然后从 iii 向汇点连一条 (1,0)(1,0)(1,0) 的边,再连一条 (1,−pi×ui)(1,-p_i\times u_i)(1,pi×ui) 的边。然后跑最大费用最大流。如果这个逼只用了一个球来抓,那么就会优先流费用为 000 的边,否则两条边都流,贡献即为 pi+ui−piuip_i+u_i-p_iu_ipi+uipiui,恰好是抓到它的期望。
时间复杂度 O(n3)O(n^3)O(n3)

代码

#include <bits/stdc++.h>
using namespace std;

const int N=2010,M=20010,Inf=1e9;
const double eps=1e-10;
int n,a,b,A,B,S,T,tot,pre[N],head[N];
double cost,p[2][N],dis[N];
bool vis[N];

struct edge
{
	int next,to,flow;
	double cost;
}e[M];

void add(int from,int to,int flow,double cost)
{
	e[++tot]=(edge){head[from],to,flow,cost};
	head[from]=tot;
	swap(from,to);
	e[++tot]=(edge){head[from],to,0,-cost};
	head[from]=tot;
}

bool spfa()
{
	memset(dis,0xcf,sizeof(dis));
	queue<int> q;
	q.push(S); dis[S]=0;
	while (q.size())
	{
		int u=q.front(); q.pop();
		vis[u]=0;
		for (int i=head[u];~i;i=e[i].next)
		{
			int v=e[i].to;
			if (e[i].flow && dis[v]<dis[u]+e[i].cost-eps)
			{
				dis[v]=dis[u]+e[i].cost; pre[v]=i;
				if (!vis[v]) { vis[v]=1; q.push(v); }
			}
		}
	}
	return dis[T]>0;
}

void addflow()
{
	int minf=Inf;
	for (int i=T;i!=S;i=e[pre[i]^1].to)
		minf=min(minf,e[pre[i]].flow);
	for (int i=T;i!=S;i=e[pre[i]^1].to)
	{
		e[pre[i]].flow-=minf;
		e[pre[i]^1].flow+=minf;
	}
	cost+=dis[T]*minf;
}

void MCMF()
{
	while (spfa()) addflow();
}

int main()
{
	memset(head,-1,sizeof(head));
	tot=1; S=N-1; T=N-2; A=N-3; B=N-4;
	scanf("%d%d%d",&n,&a,&b);
	for (int i=1;i<=n;i++) scanf("%lf",&p[0][i]);
	for (int i=1;i<=n;i++) scanf("%lf",&p[1][i]);
	for (int i=1;i<=n;i++)
	{
		add(A,i,1,p[0][i]); add(B,i,1,p[1][i]);
		add(i,T,1,0); add(i,T,1,-p[0][i]*p[1][i]);
	}
	add(S,A,a,0); add(S,B,b,0);
	MCMF();
	printf("%.10lf",cost);
	return 0;
}
#region アセンブリ JAFBusinessMapCommon, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null // D:\JAFRSAS06010_ウェブ受付機能\011\JAFRSAS\Lib\JAFBusinessMapCommon.dll // Decompiled with ICSharpCode.Decompiler 8.2.0.7535 #endregion using System; using System.Collections.Generic; using System.IO; using System.Text.Json; using GCIO; using JAFBusinessMapCommon.SubClass; using JAFCommon.Function; namespace JAFBusinessMapCommon; public class GyomuMapCommon { public enum IconCategory { Kichi, ShiteiKojo, KichiKatsudouBasho, ShiteiKatsudouBasho, KousenNoboriKP, KousenKudariKP, Shutsudosaki, TaikiBasho, Nyukosaki, gosha_sagyo_stop, gosha_shutudo_stop, gosha_ido_stop, gosha_shireimati_stop, gosha_kyukei_stop, gosha_emergency_stop, gosha_doutaiijou_stop, gosha_sonota_stop, gosha_sagyo_move, gosha_shutudo_move, gosha_ido_move, gosha_shireimati_move, gosha_kyukei_move, gosha_emergency_move, gosha_doutaiijou_move, gosha_sonota_move } public enum AreaLayerCategory { goshaShitei, shutsudoMiawase, idouJikanhosei } public struct ItemSelection { public bool IsFinished { get; set; } public int Result { get; set; } public string[] ItemId { get; set; } public double[][] ClickPos { get; set; } public string RequestId { get; set; } } public struct ResultAddcharToAddinf { public string PrefCd { get; set; } public string CityCd { get; set; } public string OazaCd { get; set; } public string AzaCode { get; set; } public string KanjiPrefName { get; set; } public string KatakanaPrefName { get; set; } public string KanjiCityName { get; set; } public string KatakanaCityName { get; set; } public string KanjiOazaName { get; set; } public string KatakanaOazaName { get; set; } public string KanjiAzaName { get; set; } public string KatakanaAzaName { get; set; } public double Latitude { get; set; } public double Longitude { get; set; } } public struct AddressCode { public string PrefCd { get; set; } public string CityCd { get; set; } public string OazaCd { get; set; } public string AzaCode { get; set; } public string KanjiPrefName { get; set; } public string KatakanaPrefName { get; set; } public string KanjiCityName { get; set; } public string KatakanaCityName { get; set; } public string KanjiOazaName { get; set; } public string KatakanaOazaName { get; set; } public string KanjiAzaName { get; set; } public string KatakanaAzaName { get; set; } } public const int DRAW_DATA = 1; public const int DELETE_DATA = 0; public const int SUCCESS = 0; public const int FAILURE = -1; public const int MAP_SUCCESS = 0; public const int MAP_CANCEL = -1; public const int MAP_FAILURE = -2; public const int OK = 0; public const int CANCEL = -1; public const int MAP_FILTER_AND = 1; public const int MAP_FILTER_OR = 2; public const int MAP_FILTER_ITEMID = 3; public const string MAP_SETTING_PATH = "appsettings.json"; public const string LAYERNAME_GENERAL = "GENERAL"; public const string LAYERNAME_AZACHOME = "Fig_AZA"; public readonly string[] IconLayerName = new string[10] { "Kichi", "Shitei", "KichiKatsudouBasho", "ShiteiKatsudouBasho", "KousenKP1", "KousenKP2", "ANKEN_SYUTUDOU", "ANKEN_TAIKI", "ANKEN_NYUKO", "GOUSHA_INFO" }; public readonly string[] AreaLayerName = new string[3] { "GoushaShiteiA", "SyutudouMiawaseA", "IdouJikanhoseiA" }; public const string GYOMU_SERVICE_NAME = "業務共通機能"; public const string JAFRSZO99010_EVENT_P010 = "支部コード→緯度経度変換"; public const string JAFRSZO99010_EVENT_P011 = "地図初期化機能"; public const string JAFRSZO99010_EVENT_P012 = "地図描画"; public const string JAFRSZO99010_EVENT_P013 = "アイコン描画機能"; public const string JAFRSZO99010_EVENT_P014 = "アイコン表示切替機能"; public const string JAFRSZO99010_EVENT_P017 = "直線距離測定"; public const string JAFRSZO99010_EVENT_P018 = "マーク判定"; public const string JAFRSZO99010_EVENT_P019 = "直線描画"; public const string JAFRSZO99010_EVENT_P020 = "号車軌跡描画"; public const string JAFRSZO99010_EVENT_P021 = "エリア範囲表示(円形)"; public const string JAFRSZO99010_EVENT_P022 = "エリア範囲選択(矩形)"; public const string JAFRSZO99010_EVENT_P023 = "エリア範囲選択(円形)"; public const string JAFRSZO99010_EVENT_P024 = "行政界エリア描画"; public const string JAFRSZO99010_EVENT_P025 = "住所文字列→座標変換"; public const string JAFRSZO99010_EVENT_P026 = "緯度経度→住所コード変換"; public const string JAFRSZO99010_EVENT_P032 = "エリア範囲表示(矩形)"; public const string JAFRSZO99010_EVENT_P033 = "ポリゴン全削除"; public const string JAFRSZO99010_EVENT_P052 = "住所文字列→住所情報"; public const string JAFRSZO99010S013 = "JAFRSZO99010S013"; public const string JAFRSCO99010S014 = "JAFRSCO99010S014"; public const string JAFRSCO99010S015 = "JAFRSCO99010S015"; public const string JAFRSCO99010S016 = "JAFRSCO99010S016"; public const string JAFRSZO99010EL00002 = "JAFRSZO99010EL00002"; public const string JAFRSCO99010EC00011 = "JAFRSCO99010EC00011"; public JAFCommonDbAccess dbInstance = new JAFCommonDbAccess(); public static Dictionary<string, object?> eventResult = new Dictionary<string, object>(); public (int result, string? adrString, double latitude, double longitude) ConvertCoordinates(string shibuCd) { int num = -1; string empty = string.Empty; double num2 = 0.0; double num3 = 0.0; return (result: 0, adrString: "東京都千代田区千代田1-1", latitude: 35.685175, longitude: 139.752799); } public int SetupMap(GeoConicIO gc, string termNo, string basicAuthInfo, double latitude, double longitude, double[] scales, double initScale) { int num = -1; return 0; } public int DrawMap(GeoConicIO gc, double cntrLat, double cntrLon, int mapScale) { int num = -1; return 0; } public (int result, string itemId) DrawIcon(GeoConicIO gc, int drawErase, IconCategory iconType, string iconId, string bottomString, string bottomStyleCd, string topString, string topStyleCd, string innerString, string innerStyleCd, double ido, double keido, string itemId) { int num = -1; string empty = string.Empty; return (result: 0, itemId: "0123456"); } public int ToggleIconDisplay(GeoConicIO gc, List<IconCategory> dispIconTypeList) { int num = -1; return 0; } public (int result, double distance) MeasureLinearDistance(GeoConicIO gc, double[] startLatLon, double[] endLatLon) { int num = -1; double num2 = 0.0; return (result: 0, distance: 1.23); } public (int result, IconCategory? iconCategory) DetermineMark(GeoConicIO gc, string itemId) { int num = -1; IconCategory? iconCategory = null; int num2 = -1; return (result: 0, iconCategory: IconCategory.Shutsudosaki); } public (int result, string? itemId) DrawLine(GeoConicIO gc, int drawErase, double[] startLatLon, double[] endLatLon, string? itemId) { int num = -1; string text = null; return (result: 0, itemId: "0123456"); } public (int result, string? itemId) DrawLocus(GeoConicIO gc, int drawErase, double[][] latLonArray, string? itemId) { int num = -1; string text = null; return (result: 0, itemId: "0123456"); } public (int result, string? itemId) RenderCircularArea(GeoConicIO gc, int drawErase, double[] idoKeido, int radius, string? itemId) { int num = -1; string text = null; return (result: 0, itemId: "123456"); } public (int result, string[] addressCdList, string[] addressIdList, string[] goshaIdList, string[] kyuenIraiIdList) SelectAreaShortShape(GeoConicIO gc) { return (result: 0, addressCdList: new string[1] { "12345678901" }, addressIdList: new string[1] { "2345678" }, goshaIdList: new string[1] { "345678" }, kyuenIraiIdList: new string[1] { "456789" }); } public (int result, string[] addressCdList, string[] addressIdList, string[] goshaIdList, string[] kyuenIraiIdList) RenderCircleArea(GeoConicIO gc) { return (result: 0, addressCdList: new string[1] { "12345678901" }, addressIdList: new string[1] { "2345678" }, goshaIdList: new string[1] { "345678" }, kyuenIraiIdList: new string[1] { "456789" }); } public (int result, string[]? itemIdList) DrawAdministrativeBoundary(GeoConicIO gc, int drawErase, int areaType, string[] addrCdList, string areaCd, string[] areaIdList) { int num = -1; string[] array = null; string empty = string.Empty; return (result: 0, itemIdList: new string[2] { "0123456", "0246802" }); } public (int result, double latitude, double longitude) TransformCoordinates(string addrWords) { int num = -1; double num2 = 0.0; double num3 = 0.0; return (result: 0, latitude: 35.681236, longitude: 139.767125); } public AddressCode? ConvertAddressCode(GeoConicIO gc, double lat, double lon) { AddressCode? addressCode = null; string empty = string.Empty; string empty2 = string.Empty; AddressCode value = default(AddressCode); value.PrefCd = "13"; value.CityCd = "001"; value.OazaCd = "002"; value.AzaCode = "003"; value.KanjiPrefName = "東京都"; value.KatakanaPrefName = "トウキョウト"; value.KanjiCityName = "千代田区"; value.KatakanaCityName = "チヨダク"; value.KanjiOazaName = "九段南"; value.KatakanaOazaName = "クダンミナミ"; value.KanjiAzaName = "1丁目"; value.KatakanaAzaName = "1チョウメ"; return value; } public int DisplayAreaRangeRectangle() { return 0; } public int DeleteAllPolygons(GeoConicIO gc, string[] itemIdList) { int num = -1; return 0; } public ResultAddcharToAddinf? ChangeAddcharToAddinf(string addressChar) { ResultAddcharToAddinf? resultAddcharToAddinf = null; ResultAddcharToAddinf value = default(ResultAddcharToAddinf); value.PrefCd = "13"; value.CityCd = "001"; value.OazaCd = "002"; value.AzaCode = "003"; value.KanjiPrefName = "東京都"; value.KatakanaPrefName = "トウキョウト"; value.KanjiCityName = "千代田区"; value.KatakanaCityName = "チヨダク"; value.KanjiOazaName = "九段南"; value.KatakanaOazaName = "クダンミナミ"; value.KanjiAzaName = "1丁目"; value.KatakanaAzaName = "1チョウメ"; value.Latitude = 35.681236; value.Longitude = 139.767125; return value; } private MapSettings? ReadSettings() { MapSettings mapSettings = null; try { string json = File.ReadAllText("appsettings.json"); return JsonSerializer.Deserialize<MapSettings>(json); } catch (Exception) { return null; } } } #if false // 逆コンパイルのログ キャッシュ内の '313' 個の項目 ------------------ 解決: "System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 1 つのアセンブリが見つかりました: 'System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 読み込み元: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.18\ref\net8.0\System.Runtime.dll' ------------------ 解決: "PresentationFramework, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 名前 'PresentationFramework, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' で見つけることができませんでした ------------------ 解決: "JAFCommon, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" 1 つのアセンブリが見つかりました: 'JAFCommon, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 読み込み元: 'D:\JAFRSAS06010_ウェブ受付機能\011\JAFRSAS\Lib\JAFCommon.dll' ------------------ 解決: "System.Collections, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 1 つのアセンブリが見つかりました: 'System.Collections, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 読み込み元: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.18\ref\net8.0\System.Collections.dll' ------------------ 解決: "System.Data.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 1 つのアセンブリが見つかりました: 'System.Data.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 読み込み元: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.18\ref\net8.0\System.Data.Common.dll' ------------------ 解決: "JAFBusinessCommon, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" 1 つのアセンブリが見つかりました: 'JAFBusinessCommon, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 読み込み元: 'D:\JAFRSAS06010_ウェブ受付機能\011\JAFRSAS\Lib\JAFBusinessCommon.dll' ------------------ 解決: "GeoConicIO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" 名前 'GeoConicIO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' で見つけることができませんでした ------------------ 解決: "Gis, Version=3.12.8.1, Culture=neutral, PublicKeyToken=null" 名前 'Gis, Version=3.12.8.1, Culture=neutral, PublicKeyToken=null' で見つけることができませんでした ------------------ 解決: "System.Drawing.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 1 つのアセンブリが見つかりました: 'System.Drawing.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 読み込み元: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.18\ref\net8.0\System.Drawing.Primitives.dll' ------------------ 解決: "System.Text.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" 1 つのアセンブリが見つかりました: 'System.Text.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' 読み込み元: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.18\ref\net8.0\System.Text.Json.dll' ------------------ 解決: "System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 1 つのアセンブリが見つかりました: 'System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 読み込み元: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.18\ref\net8.0\System.Linq.dll' ------------------ 解決: "System.Runtime.InteropServices, Version=8.0.0.0, Culture=neutral, PublicKeyToken=null" 1 つのアセンブリが見つかりました: 'System.Runtime.InteropServices, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 読み込み元: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.18\ref\net8.0\System.Runtime.InteropServices.dll' ------------------ 解決: "System.Runtime.CompilerServices.Unsafe, Version=8.0.0.0, Culture=neutral, PublicKeyToken=null" 1 つのアセンブリが見つかりました: 'System.Runtime.CompilerServices.Unsafe, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 読み込み元: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.18\ref\net8.0\System.Runtime.CompilerServices.Unsafe.dll' #endif
最新发布
11-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值