01分数规划

背景:根据楼教主回忆,曾经在一场比赛中秒掉了一道最优比例生成树问题,导致很多人跟风失败,最终悲剧。

  • 什么是01分数规划呢?

这样的等式求最大,最小即为01分数规划。  

如果你不知道该如何去解,你可能会去贪心,DP去做,但是这样是很复杂的。

  • 解法:二分,迭代(计算几何大佬都知道这种方案,但是我不是)

  • 直接二分ans,​ ​ ​ 根据符号二分转移。

例题一:pku 2796

题意: 最大。

#include <stdio.h>
#include <algorithm>

using namespace std;

const int maxn = ;

int n,k;
double a[maxn],b[maxn];
double c[maxn];

bool cmp(double a,double b) {
return a > b;
}

bool calc(double x) {
for(int i = ; i < n; i++)
c[i] = a[i] - x*b[i];
sort(c,c+n,cmp);

double sum = ;
for(int i = ; i < n-k; i++)
sum +=c[i];
if(sum>=) return true;
return false;

}

int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&k),n) {

for(int i = ; i < n; i++) scanf("%lf",&a[i]);
for(int i = ; i < n; i++) scanf("%lf",&b[i]);

double l = ,r = ;

while(r-l>1e-) {
double mid = (l + r)/;

if(calc(mid))
l = mid;
else r = mid;

}
printf("%.0lf\n",l*);

}
return ;
}

例题二:pku 2728 最优比例生成树

题意:给定n 个点,坐标(x,y,z),n条无向边的图,国王将这n个点连起来(生成树),建一条边有花费, 求单位最小花费最小比例。

同理:二分这个比例,边权为 ,最小生成树 ans >= 0,说明 x过小,二分转移 l = mid;

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = ;

double maps[maxn][maxn];
bool vis[maxn];
double dis[maxn];

int n;

double Prim() {
memset(vis,false,sizeof(vis));
for(int i = ; i<= n; i++)
dis[i] = ;

double ans = ;
dis[] = ;

for(int i = ; i <= n; i++) {
double tmp = ;
int k = ;

for(int j = ; j <= n; j++) {
if(!vis[j]&&dis[j]<tmp) {
tmp = dis[j];
k = j;
}
}

vis[k] = true;
ans += tmp;

for(int j = ; j<= n; j++) {
if(!vis[j]&&dis[j]>maps[k][j])
dis[j] = maps[k][j];
}

}
return ans;
}

struct Node {
double x,y,z;
}nodes[maxn];

double dist(int i,int j,double x) {
double fx = fabs(nodes[i].x-nodes[j].x);
double fy = fabs(nodes[i].y-nodes[j].y);
double fz = fabs(nodes[i].z-nodes[j].z);
return fz - x*sqrt(fx*fx+fy*fy);
}

double eps = 1e-;

int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n),n) {

for(int i = ; i <= n; i++) scanf("%lf%lf%lf",&nodes[i].x,&nodes[i].y,&nodes[i].z);

double l = ,r = ;

while(r-l>1e-) {
double mid = (r+l)/;

for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
maps[i][j] = dist(i,j,mid);

double ans = Prim();

if(ans<=)
r = mid;
else l = mid;
}

printf("%.3f\n",l);
}

return ;
}

例题三:pku 3621 最优比例环。(双倍经验题Uva 11090,题意相反)

题意:给定一个L个节点,P条有向边的图,奶牛从一个城市出发,走一个环回到起点,点上有权值,边上也有长度,求单位长度的点权最大。

分析:还是二分 ans,由于是一个环,一条边上,算起点权值就好了。改边权, ,

由于求的是比例最大,这时SPFA,应反向松弛,才能得到最大的比例。

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = ;

struct Edge {
int from,to;
double dist;
};

struct BellmanFord
{
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
bool inq[maxn];
double d[maxn];
int p[maxn];
int cnt[maxn];

void init(int n)
{
this->n = n;
for(int i = ; i < n; i++) G[i].clear();
edges.clear();
}

void AddEdge(int from, int to, double dist)
{
edges.push_back((Edge)
{
from, to, dist
});
m = edges.size();
G[from].push_back(m-);
}

bool negativeCycle()
{
queue<int> Q;
memset(inq, , sizeof(inq));
memset(cnt, , sizeof(cnt));
for(int i = ; i < n; i++)
{
d[i] = ;
inq[] = true;
Q.push(i);
}

while(!Q.empty())
{
int u = Q.front();
Q.pop();
inq[u] = false;
for(int i = ; i < (int)G[u].size(); i++)
{
Edge& e = edges[G[u][i]];
if(d[e.to] < d[u] + e.dist) //反向松弛
{
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
if(!inq[e.to])
{
Q.push(e.to);
inq[e.to] = true;
if(++cnt[e.to] > n) return true;
}
}
}
}
return false;
}
}sol;
int L,P;
double f[maxn];
double t[maxn];

vector<Edge> edgestmp;

int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&L,&P);

sol.init(L);
for(int i = ; i < L; i++) scanf("%lf",&f[i]);
for(int i = ; i < P; i++) {
int u,v;
double dist;
scanf("%d%d%lf",&u,&v,&dist);
u--;v--;
edgestmp.push_back((Edge){u,v,dist});
sol.AddEdge(u,v,dist);
}

double l = ,r = ;
while(r-l>1e-) {
double mid = (r+l)/;

sol.init(L);

for(int i = ; i < P; i++) {
int u = edgestmp[i].from;
int v = edgestmp[i].to;
double dist = edgestmp[i].dist;
sol.AddEdge(u,v,f[u]-mid*dist);
}

if(sol.negativeCycle())
l = mid;
else r = mid;
}

printf("%.2f\n",l);
return ;
}
												

ACM-ICPC (10/12)的更多相关文章

  1. 2016 ACM/ICPC Asia Regional Qingdao Online 1001/HDU5878 打表二分

    I Count Two Three Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  2. Java in ACM/ICPC

    目录 Java在ACM/ICPC中的特点 在ACM/ICPC中使用Java需要注意的问题 Java与高精度计算 1.Java在ACM/ICPC中的特点 Java的语法和C++几乎相同 Java在执行计 ...

  3. 2016 ACM/ICPC Asia Regional Qingdao Online(2016ACM青岛网络赛部分题解)

    2016 ACM/ICPC Asia Regional Qingdao Online(部分题解) 5878---I Count Two Three http://acm.hdu.edu.cn/show ...

  4. 2017 ACM/ICPC Asia Regional Qingdao Online

    Apple Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submi ...

  5. ACM/ICPC 之 BFS(离线)+康拓展开(TSH OJ-玩具(Toy))

    祝大家新年快乐,相信在新的一年里一定有我们自己的梦! 这是一个简化的魔板问题,只需输出步骤即可. 玩具(Toy) 描述 ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具. 该玩具酷似魔方, ...

  6. ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 D. Delay Time

    Problem D. Delay Time Input file: standard input Output file: standard output Time limit: 1 second M ...

  7. 【转】ACM/ICPC生涯总结暨退役宣言—alpc55

    转自:http://hi.baidu.com/accplaystation/item/ca4c2ec565fa0b7fced4f811 ACM/ICPC生涯总结暨退役宣言—alpc55 前言 早就该写 ...

  8. hduoj 4715 Difference Between Primes 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4715 Difference Between Primes Time Limit: 2000/1000 MS (J ...

  9. hduoj 4712 Hamming Distance 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4712 Hamming Distance Time Limit: 6000/3000 MS (Java/Other ...

  10. hduoj 4707 Pet 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4707 Pet Time Limit: 4000/2000 MS (Java/Others)    Memory ...

随机推荐

  1. 《UML和模式应用(原书第3版)》目录

    学习 <UML和模式应用(原书第3版)>目标: 理解OOA/D思想 如何使用UML建模 如何使用设计模式 如何设计分层架构 目录: 第1部分 绪论 第1章 面向对象分析和设计 第2章 迭代 ...

  2. 4.整体架构和Smart Scan

    寻道时间: 外圈,比内圈要多, 即外圈是比较快的. 第一次创建grid disk 时,是创建外圈,用于存放数据的,内圈存储归档这些数据 CellCLI> CREATE GRIDDISK ALL ...

  3. vue-vli3创建的项目配置热更新

    vue-vli3创建的项目配置热更新 问题描述:使用vue-cli3创建的项目,修改代码之后,浏览器页面不会自动刷新,然而之前使用webpack初始化的vue项目修改代码之后浏览器会重新加载一下,因为 ...

  4. Ubuntu以及CentOS7修改ssh端口号详细步骤

    1.Ubuntu修改ssh端口号步骤: 1.修改sshd.config文件.执行vim etc/ssh/sshd_config.增加上我们需要增加的ssh的端口号.图例增加了5309的端口号. ESC ...

  5. 读书笔记-NIO的工作方式

    读书笔记-NIO的工作方式 1.BIO是阻塞IO,一旦阻塞线程将失去对CPU的使用权,当前的网络IO有一些解决办法:1)一个客户端对应一个处理线程:2)采用线程池.但也会出问题. 2.NIO的关键类C ...

  6. Java学习第二十四天

    1:多线程(理解) (1)JDK5以后的针对线程的锁定操作和释放操作 Lock锁 (2)死锁问题的描述和代码体现 (3)生产者和消费者多线程体现(线程间通信问题) 以学生作为资源来实现的 资源类:St ...

  7. 经典算法详解(1)斐波那契数列的n项

    斐波那契数列是一个常识性的知识,它指的是这样的一个数列,它的第一项是1,第二项是1,后面每一项都是它前面两项的和,如:1,1,2,3,5,8,13,21,34,55,89,144,233…… 说明:由 ...

  8. 【Linux相识相知】bash的特性

    命令历史 shell进程会记录用户提交执行过的命令 可以是用history查看: [root@localhost dev]# history ss -tnl ifconfig vi /etc/sysc ...

  9. 深入理解JavaScript系列(9):根本没有“JSON对象”这回事!

    前言 写这篇文章的目的是经常看到开发人员说:把字符串转化为JSON对象,把JSON对象转化成字符串等类似的话题,所以把之前收藏的一篇老外的文章整理翻译了一下,供大家讨论,如有错误,请大家指出,多谢. ...

  10. [转]在ASP.NET Core使用Middleware模拟Custom Error Page功能

    本文转自:http://www.cnblogs.com/maxzhang1985/p/5974429.html 阅读目录 一.使用场景 二..NET Core实现 三.源代码 回到目录 一.使用场景 ...