01分数规划

Posted hgangang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了01分数规划相关的知识,希望对你有一定的参考价值。

先上基本模板后面慢慢更新


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#define LL long long
#define _LL __int64
#define eps 1e-7
using namespace std;
const _LL INF = 1e18;
const int maxn = 1010;


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

int main()

while(~scanf("%d %d",&n,&k) && (n || k))

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

double l = 0.0;
double r = 1.0;
double mid;

while(fabs(r-l) > eps)

mid = (l+r)/2;

for(int i = 1; i <= n; i++)
c[i] = 1.0*a[i] - mid * 1.0 * b[i];
sort(c+1,c+1+n);
double sum = 0.0;
for(int i = k+1; i <= n; i++)
sum += c[i];
if(sum > 0)
l = mid;
else if(sum < 0)
r = mid;
else break;

mid = mid*100;
printf("%.0f\n",mid);

return 0;

————————更新

一道最小生成树上套01

Desert King poj2728

与生成树不一样的是生成树是按权最小来生成,我们这个得是cost/len,

故我们可以将01规划弄出cost-r*len作为边权跑prim,结果大于小于0来二分

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#define INF 1e9
#define M 100
#define N 1010
using namespace std;
typedef long long ll;
int n;
double dis[N][N],h[N][N],d[N][N],lowcost[N],vis[N];
struct point
double x,y,z;
a[N];
double A(int i,int j)
return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));

double prim(double num)
//memset(lowcost,0,sizeof(lowcost));
memset(vis,0,sizeof(vis));
for (int i=0;i<n;i++)
for (int j=i+1;j<n;j++)
d[j][i]=d[i][j]=h[i][j]-num*dis[i][j];
int k;
double mini,sum=0;
for (int i=0;i<n;i++)
lowcost[i]=d[0][i];
vis[0]=1;
for (int i=1;i<n;i++)
mini=INF;
k=-1;
for (int j=0;j<n;j++)
if (!vis[j]&&lowcost[j]<mini)
mini=lowcost[j],k=j;
if (k==-1) break;
sum+=lowcost[k];
vis[k]=1;
for (int j=0;j<n;j++)
if (!vis[j]&&lowcost[j]>d[k][j])
lowcost[j]=d[k][j];

return sum>=0;

int main()
ios::sync_with_stdio(false);
while(~scanf("%d",&n)&&n!=0)
memset(dis,0,sizeof(dis));
memset(h,0,sizeof(h));
for (int i=0;i<n;i++)
scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z);
for (int i=0;i<n;i++)
for (int j=i+1;j<n;j++)
dis[j][i]=dis[i][j]=A(i,j),h[j][i]=h[i][j]=abs(a[i].z-a[j].z);
double l=0,r=100.0;
while (r-l>=0.000001)
double mid=l+(r-l)/2.0;
if (prim(mid)) l=mid;
else r=mid;

printf("%.3lf\n",r);

return 0;

以上是关于01分数规划的主要内容,如果未能解决你的问题,请参考以下文章

01分数规划

01分数规划

算法微解读浅谈01分数规划

算法微解读浅谈01分数规划

算法xio讲堂#1--01分数规划

01分数规划入门