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. Open Closed Principle(OCP)开闭原则

    面向对象的最基本原则 Software entites like classes,modules and functions should be open for extension but cloa ...

  2. STL:vector用法总结

    一:介绍 vector是C++标准模板库,是一个容器,底层是数组,为连续内存.命名空间为std,所属头文件为<vector>   注意:不是<vector.h>vector存储 ...

  3. SVM之Python实现

    SVM Python实现 Python实现SVM的理论知识 SVM原始最优化问题: \[ min_{w,b,\xi}{1\over{2}}{||w||}^2 + C\sum_{i=1}^m\xi^{( ...

  4. 【IP】Linux中检测IP地址冲突

    在Windows系统中,如果本地网络IP地址出现冲突,会出现图标提示. 在Linux系统中,并没有提供相关的功能,如果本地网络采用静态IP地址配置,出现比较奇怪的网络连接问题,如ssh连接复位,可以考 ...

  5. 浅谈 .NET Framework 与 .NET Core 的区别与联系

    2017到了,咱们学点啥啊,要想知道学点啥,先弄清.NET Framework 与 .NET Core  这两个概念 .当今 net 生态系统如下: 从上面图中我们可以看到.net  主要分为三个部分 ...

  6. Win2D 官方文章系列翻译 - 预乘 Alpha

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-premultiplied-alpha/ 在计算机绘图中有两种表示颜色值不透明度的方法.Win2D 中两种方法 ...

  7. Jquery系列:设置div、span等dom结点的内容,jquery中没有innerText、innerHtml

    发现如果我在div或者其他非表单的标签中赋值,原本用普通的js就直接document.getElementById("id").innerHtml(或者其他几个)就可以了. 但是在 ...

  8. easyui datagrid 本地json数据 实现删除

    html代码:<a href='javascript:void(0);' onclick='Delete(\""+ index +"\")' class= ...

  9. HTML表单(form)的“enctype”属性

    Form元素的语法中,EncType表明提交数据的格式 属性值: application/x-www-form-urlencoded:在发送前编码所有字符(默认) multipart/form-dat ...

  10. 原生js简单实现拖拽效果

    实现弹窗拖拽效果的原理是:按下鼠标并移动——拖拽移动物体,抬起鼠标——停止移动.主要触发三个事件:onmousedown.onmousemove以及onmouseup: 首先搭建结构:一个宽350px ...