AcWing 348. 沙漠之王(0/1分数规划)

2024-01-08 16:59

本文主要是介绍AcWing 348. 沙漠之王(0/1分数规划),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

0/1分数规划

从该题可以归纳出的0/1分数规划的一般模型:给定正整数 a 1 , a 2 . . . a n a_{1},a_{2}...a_{n} a1,a2...an以及 b 1 , b 2 . . . b n b_{1}, b_{2}...b_{n} b1,b2...bn从中选出若干对的a和b的和的商,求商的最大值Max或者最小值Min,即:
∑ a [ i ] ∑ b [ i ] ∈ [ M i n , M a x ] \frac{\sum_{}a[i]}{\sum_{}b[i]}∈[Min, \ Max] b[i]a[i][Min, Max]

由于不知道他们的商是多少,我们不妨先假设 ∑ a [ i ] ∑ b [ i ] = m \frac{\sum_{}a[i]}{\sum_{}b[i]}=m b[i]a[i]=m

find_Min

1.若 任意 ∑ ( a [ i ] − m ∗ b [ i ] ) ≥ 0 \sum (a[i] - m * b[i]) ≥ 0 (a[i]mb[i])0 ∑ ( a [ i ] − m ∗ b [ i ] ) m i n ≥ 0 \sum (a[i] - m * b[i])_{min}≥ 0 (a[i]mb[i])min0 ( ∑ a [ i ] ∑ b [ i ] ) m i n ≥ m (\frac{\sum a[i]}{\sum b[i]})_{min} ≥ m (b[i]a[i])minm
M i n ≥ m Min ≥ m Minm
2.若 存在 ∑ ( a [ i ] − m ∗ b [ i ] ) < 0 \sum (a[i] - m * b[i]) < 0 (a[i]mb[i])<0 ∑ ( a [ i ] − m ∗ b [ i ] ) m i n < 0 \sum (a[i] - m * b[i])_{min}< 0 (a[i]mb[i])min<0 ( ∑ a [ i ] ∑ b [ i ] ) m i n < m (\frac{\sum a[i]}{\sum b[i]})_{min} < m (b[i]a[i])min<m
M i n < m Min < m Min<m

find_Max

1.若 存在 ∑ ( a [ i ] − m ∗ b [ i ] ) ≥ 0 \sum (a[i] - m * b[i]) ≥ 0 (a[i]mb[i])0 ∑ ( a [ i ] − m ∗ b [ i ] ) m a x ≥ 0 \sum (a[i] - m * b[i])_{max}≥ 0 (a[i]mb[i])max0 ( ∑ a [ i ] ∑ b [ i ] ) m a x ≥ m (\frac{\sum a[i]}{\sum b[i]})_{max} ≥ m (b[i]a[i])maxm
M a x ≥ m Max ≥ m Maxm
2.若 任意 ∑ ( a [ i ] − m ∗ b [ i ] ) < 0 \sum (a[i] - m * b[i]) < 0 (a[i]mb[i])<0 ∑ ( a [ i ] − m ∗ b [ i ] ) m a x < 0 \sum (a[i] - m * b[i])_{max}< 0 (a[i]mb[i])max<0 ( ∑ a [ i ] ∑ b [ i ] ) m a x < m (\frac{\sum a[i]}{\sum b[i]})_{max} < m (b[i]a[i])max<m
M a x < m Max < m Max<m

二分

综上所诉,我们可以二分查找m
1.当 ∑ a [ i ] ∑ b [ i ] ≥ m \frac{\sum a[i]}{\sum b[i]} ≥ m b[i]a[i]m,即m ≤ {Max or Min},→ l = mid;
2.当 ∑ a [ i ] ∑ b [ i ] < m \frac{\sum a[i]}{\sum b[i]} < m b[i]a[i]<m,即m > {Max or Min},→ r = mid;


348. 沙漠之王

在这里插入图片描述
思路:
成本为c, 长度为v
1.题意求生成树的 ∑ c [ i ] ∑ v [ i ] \frac{\sum c[i]}{\sum v[i]} v[i]c[i]的Min, 不妨设 ∑ c [ i ] ∑ v [ i ] = m \frac{\sum c[i]}{\sum v[i]} = m v[i]c[i]=m
2.若 任意 ∑ ( c [ i ] − m ∗ v [ i ] ) ≥ 0 \sum (c[i] - m * v[i]) ≥ 0 (c[i]mv[i])0
⇔ 以 ( c [ i ] − m ∗ v [ i ] ) (c[i] - m * v[i]) (c[i]mv[i])为边权的最小生成树
∑ ( c [ i ] − m ∗ v [ i ] ) m i n ≥ 0 \sum (c[i] - m * v[i])_{min}≥ 0 (c[i]mv[i])min0
( ∑ c [ i ] ∑ v [ i ] ) m i n ≥ m (\frac{\sum c[i]}{\sum v[i]})_{min} ≥ m (v[i]c[i])minm
即 m 小于等于Min
则 l = mid 反正则 r = mid
3. 稠密图用prim算法 O ( n 2 ) O(n^2) O(n2), 用Kruskal O ( m l o g m ) O(mlogm) O(mlogm) , m = n 2 m = n ^ 2 m=n2 会超时

样例输入:

4
0 0 0
0 1 1
1 1 2
1 0 3
0

样例输出:

1.000

代码:

//最优比例生成树
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1005, M = 1e6 + 10, INF = 10000005;
typedef pair<int, int> PII;
int n;
double mm;double c[N][N], v[N][N], dist[N];
bool st[N];struct Point{int x, y, d;
}point[N];double dis(Point a, Point b)
{return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}double prim(double m)
{for(int i = 1; i <= n; i ++ ) dist[i] = INF;memset(st, false, sizeof st);double sum = 0;for(int i = 0; i < n; i ++ ){int t = -1;for(int j = 1; j <= n; j ++ )if(!st[j] && (t == -1 || dist[j] < dist[t]))t = j;if(i) sum += dist[t];for(int j = 1; j <= n; j ++ ){double tmp = c[t][j] - v[t][j] * m;if(!st[j]) dist[j] = min(dist[j], tmp);}st[t] = true;}return sum;
}int main()
{while(cin >> n){if(n == 0) break;for(int i = 1; i <= n; i ++ ){int x, y, d;cin >> x >> y >> d;point[i] = {x, y, d};}for(int i = 1; i <= n; i ++ )for(int j = i + 1; j <= n; j ++ ){c[i][j] = c[j][i] = (double)abs(point[i].d - point[j].d);v[i][j] = v[j][i] = dis(point[i], point[j]);}double l = 0, r = 100;while(r - l >= 1e-4){double mid = (l + r) / 2.0;if(prim(mid) >= 0) l = mid;else r = mid;}printf("%.3lf\n", r);        }return 0;
}

 

这篇关于AcWing 348. 沙漠之王(0/1分数规划)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/584171

相关文章

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

轨迹规划-B样条

B样条究竟是干啥的?白话就是给出一堆点,用样条的方式,给这些点连接起来,并保证丝滑的。 同时B样条分为准均匀和非均匀,以下为准均匀为例。 参考链接1:https://zhuanlan.zhihu.com/p/50626506https://zhuanlan.zhihu.com/p/50626506 参考链接2: https://zhuanlan.zhihu.com/p/536470972h

PMBOK® 第六版 规划进度管理

目录 读后感—PMBOK第六版 目录 规划进度管理主要关注为整个项目期间的进度管理提供指南和方向。以下是两个案例,展示了进度管理中的复杂性和潜在的冲突: 案例一:近期,一个长期合作的客户因政策要求,急需我们为多家医院升级一个小功能。在这个过程中出现了三个主要问题: 在双方确认接口协议后,客户私自修改接口并未通知我们,直到催进度时才发现这个问题关于UI设计的部分,后台开发人员未将其传递给

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划

LeetCode:3177. 求出最长好子序列 II 哈希表+动态规划实现n*k时间复杂度

3177. 求出最长好子序列 II 题目链接 题目描述 给你一个整数数组 nums 和一个非负整数k 。如果一个整数序列 seq 满足在下标范围 [0, seq.length - 2] 中 最多只有 k 个下标i满足 seq[i] != seq[i + 1] ,那么我们称这个整数序列为好序列。请你返回 nums中好子序列的最长长度。 实例1: 输入:nums = [1,2,1,1,3],

【AcWing】851. 求最短路

spfa算法其实是对贝尔曼福特算法做一个优化。 贝尔曼福特算法会遍历所有边来更新,但是每一次迭代的话我不一定每条边都会更新,SPFA是对这个做优化。 如果说dist[b]在当前这次迭代想变小的话,那么一定是dist[a]变小了,只有a变小了,a的后继(b)才会变小。 用宽搜来做优化,用一个队列,队列里边存的就是所有变小了的结点(队列里存的是待更新的点)。 基本思路就是我更新过谁,我再拿