poj1018computing system

来源:互联网 发布:java输入流读取文件 编辑:程序博客网 时间:2024/05/30 05:12

用的暴搜,枚举每一个可能的带宽,维护一个最大的b/p,即答案;

google了下,还有其他思想,

对带宽排序:离散化思想,

枚举从最小带宽(每一行的最小值中的最小值)到最大带宽(每一行的最大值中的最小值)之间的值:贪心思想

b/p是一个关于b的单峰函数:3分思想。(用这个在加上二分查找和快排优化的话应该可以0msAC,以后回过头再重做吧,先留着,太菜了。)


我的AC代码:

# include <stdlib.h># include <string.h># include <string># include <stdio.h>struct device {int b;int p;};device d[110][110];int sum;int cmp(const void *x, const void *y) {return ((device*)(x))->b - ((device*)(y))->b;}int go(int m) {for (int i = 0; i < m; ++ i) {qsort (d[i] + 1, d[i][0].b, sizeof(device), cmp);#ifdef DEBUGfor (int j = 1; j <= d[i][0].b; ++ j) {printf ("%d-%d ", d[i][j].b, d[i][j].p);}printf ("\n");#endif}double ans = 0;int up = 0;int down = 0;for (int i = 0; i < m; ++ i) {for (int j = 1; j <= d[i][0].b; ++ j) {up = d[i][j].b;down = d[i][j].p;for (int x = 0; x < m; ++ x) {if (x == i) continue;int min = 99999999;for (int y = 1; y <= d[x][0].b; ++ y) {if (d[x][y].b < up) continue;if (d[x][y].p < min) {min = d[x][y].p;}}down += min;}double tmp = (double)up / down;#ifdef DEBUGprintf ("%.3lf\n", tmp);#endifans = ans > tmp ? ans : tmp; }}printf ("%.3lf\n", ans);return 0;}int main () {int n,m;scanf ("%d", &n);while (n -- ) {scanf ("%d", &m);for (int i = 0; i < m; ++ i) {int t;scanf ("%d", &t);d[i][0].p = d[i][0].b = t;for (int j = 1; j <= t; ++ j) {scanf ("%d %d", &(d[i][j].b), &(d[i][j].p));}}go(m);}return 0;}




大神的3分代码:

#include <iostream>#include <algorithm>#include <cmath>using namespace std;int n;int t;int len[111];int b[111][111];int p[111][111];int a[222222];int m;double calc(int x){double sum(0);for (int i=1; i<=n; i++){int xiao = 2147483647;for (int j=1; j<=len[i]; j++)if (b[i][j] >= x) xiao = min(xiao, p[i][j]);sum += xiao;}return x / sum;}int main(void){int i,j,k,ci,cici,cicici;for (scanf("%d", &t); t; t--){scanf("%d", &n);for (i=1; i<=n; i++){scanf("%d", &len[i]);for (j=1; j<=len[i]; j++){scanf("%d%d", &b[i][j], &p[i][j]);a[++m] = b[i][j];}}sort(a+1, a+1+m);int left = 1, right = m, mid1, mid2;double f1, f2;while(left + 1 < right){mid1 = (left + right) / 2;mid2 = (mid1 + right) / 2;f1 = calc(a[mid1]);f2 = calc(a[mid2]);if (f1 < f2) left = mid1;else right = mid2;}printf("%.3lf\n", max(calc(a[left]), calc(a[right])));}return 0;}


原创粉丝点击