码迷,mamicode.com
首页 > 其他好文 > 详细

01分数规划

时间:2019-09-14 01:04:05      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:efi   false   ble   clu   eof   math   def   int   syn   

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


#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分数规划

标签:efi   false   ble   clu   eof   math   def   int   syn   

原文地址:https://www.cnblogs.com/hgangang/p/11517952.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!