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

专题:01分数规划

时间:2015-07-19 11:51:26      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:

poj2976

普通的01分数规划

大意:给定A数组B数组,从中选择N-K个使得R最大,输出Round(100*R);

技术分享
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;

const int N = 1009;
const double Eps = 1e-7;
int n, k;
double a[N], b[N];
double l, r, mid;
int main() {
    while ( scanf ( "%d %d", &n, &k ) != EOF ) {
        if ( n == 0 && k == 0 ) break;
        for ( int i = 1; i <= n; ++i ) {
            scanf ( "%lf", &a[i] );
        }
        for ( int i = 1; i <= n; ++i ) {
            scanf ( "%lf", &b[i] );
        }
        l = 0., r = 1.;
        double t[N], sum;
        while ( fabs ( r - l ) > Eps ) {
            sum = 0;
            mid = 1.* ( l + r ) / 2;
            for ( int i = 1; i <= n; ++i ) {
                t[i] = 1.*a[i] - mid * b[i];
            }
            sort ( t + 1, t + 1 + n );
            for ( int i = k + 1; i <= n; ++i ) {
                sum += t[i];
            }
            if ( sum > 0 ) {
                l = mid;
            } else {
                r = mid;
            }
        }
        printf ( "%.0f\n",  100 * l );
    }
}
二分法

 

 

poj2728

最优比率生成树

大意:给定一张图,每条边有一个收益值和一个花费值,求一个生成树,要求花费/收益最小,输出这个值

技术分享
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;

const int N = 1009;
const double Eps = 1e-4;
int n, k;
double x[N], y[N], h[N];
double dis[N][N], dh[N][N];
double prim ( double k )
{
    int vis[N] = {0, 1}, s = 1, u = 1, v;
    double c[N], sum = 0.;

    while ( s < n ) {
        double tem = 0x7fffffff;
        for ( int i = 1; i <= n; ++i ) {
            if ( !vis[i] ) {
                double bit = dh[u][i] - k * dis[u][i];
                if ( bit < c[i] || u == 1 ) {
                    c[i] = bit;
                }
                if ( tem > c[i] ) {
                    tem = c[i];
                    v = i;
                }
            }
        }
        sum += c[v];
        vis[v] = 1;
        u = v;
        ++s;
    }
    return sum;
}

int main()
{
    while ( scanf ( "%d", &n ) != EOF ) {
        if ( n == 0 ) break;
        for ( int i = 1; i <= n; ++i ) {
            scanf ( "%lf %lf %lf", &x[i], &y[i], &h[i] );
        }
        for ( int i = 1; i <= n; ++i ) {
            for ( int j = i + 1; j <= n; ++j ) {
                dis[i][j] = dis[j][i] = sqrt ( ( x[i] - x[j] ) * ( x[i] - x[j] ) + ( y[i] - y[j] ) * ( y[i] - y[j] ) );
                dh[i][j] = dh[j][i] = fabs ( h[i] - h[j] );
            }
        }
        double l = 0., r = 10000.0;
        while ( fabs ( r - l ) > Eps ) {
            double mid = ( l + r ) / 2;
            if ( prim ( mid ) >= 0 ) l = mid;
            else r = mid;
        }
        printf ( "%0.3f\n", l );
    }
}
二分法(700ms)
技术分享
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;

const int N = 1009;
const double Eps = 1e-4;
int n, k;
double x[N], y[N], h[N];
double dis[N][N], dh[N][N];
double prim ( double k )
{
    int vis[N] = {0, 1},pos[N]={0}, s = 1, u = 1, v;
    double c[N];
    double cost = 0., len = 0.;
    while ( s < n ) {
        double tem = 0x7fffffff;
        for ( int i = 1; i <= n; ++i ) {
            if ( !vis[i] ) {
                double bit = dh[u][i] - k * dis[u][i];
                if ( u == 1 || bit < c[i] ) {
                    c[i] = bit;
                    pos[i]=u;
                }
                if ( tem > c[i] ) {
                    tem = c[i];
                    v = i;
                }
            }
        }
        cost += dh[pos[v]][v], len += dis[pos[v]][v];
        vis[v] = 1;
        u = v;
        ++s;
    }
    return cost / len;
}

int main()
{
    while ( scanf ( "%d", &n ) != EOF ) {
        if ( n == 0 ) break;
        for ( int i = 1; i <= n; ++i ) {
            scanf ( "%lf %lf %lf", &x[i], &y[i], &h[i] );
        }
        for ( int i = 1; i <= n; ++i ) {
            for ( int j = i + 1; j <= n; ++j ) {
                dis[i][j] = dis[j][i] = sqrt ( ( x[i] - x[j] ) * ( x[i] - x[j] ) + ( y[i] - y[j] ) * ( y[i] - y[j] ) );
                dh[i][j] = dh[j][i] = fabs ( h[i] - h[j] );
            }
        }
        double ans = 0., k;
        while ( 1 ) {
            k = prim ( ans );
            if ( fabs ( k - ans ) < Eps ) break;
            ans = k;
        }
        printf ( "%0.3f\n", ans );
    }
}
Dinkelbach(157ms)

 

 

poj3621

专题:01分数规划

标签:

原文地址:http://www.cnblogs.com/keam37/p/4658334.html

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