普通的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 ); } }
二分法
最优比率生成树
大意:给定一张图,每条边有一个收益值和一个花费值,求一个生成树,要求花费/收益最小,输出这个值
#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)
时间: 2024-10-13 05:41:28