POJ 1018:Communication System - DP

来源:互联网 发布:three.js webgl 编辑:程序博客网 时间:2024/05/22 12:24
POJ 1018 
题意:
某公司要建立一套通信系统,有n个厂家提供生产所需要的网线。而每个厂家生产的同种网线都会存在两个方面的差别:带宽bandwidths 和 价格prices。

现在需要在每个厂家选择一件网线,考虑到性价比问题,要求所挑选出来的n件设备,要使得B/P最大。输出这个比值保留3位小数。(其中B为这n件设备的带宽的最小值,P为这n件设备的总价。)

思路:

dp[i][j]:取到第 i 个厂家的网线,其中最小带宽为 j 的最小费用i代表的是选取前i个物品,j为当前最小的带宽。


选择第i个厂家时,需要枚举该厂家的所有网线,选择该k网线时,和不选择该k网线。则

dp[i][final] = min(dp[i - 1][j] + p[k], dp[i][final])。

此处final = min(j,b[k])。计算结果时所用的带宽是最小值,故枚举时需要考虑的是最小带宽。


状态转移方程:dp[i][j] = min(dp[i - 1][k] + p, dp[i][j]);

#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const int inf = 0x3f3f3f3f;int dp[110][1200];//dp[i][j]:取到第 i 个厂家的网线,其中最小带宽为 j 的最小费用int b[110], p[110];int main(){int T;scanf("%d", &T);while(T--){int n, m, maxb = 0;scanf("%d", &n);for(int i = 0; i < n; i++)for(int j = 0; j < 1200; j++)dp[i][j] = inf;memset(b, 0, sizeof(b));memset(p, 0, sizeof(p));for(int i = 0; i < n; i++){scanf("%d", &m);for(int j = 0; j < m; j++){scanf("%d%d", &b[j], &p[j]);maxb = max(maxb, b[j]);}if(i == 0){for(int j = 0; j < m; j++)dp[0][b[j]] = p[j];//保证不会出现 b相同但是p不同continue;}int tmp;for(int k = 0; k <= maxb; k++){for(int j = 0; j < m; j++){tmp = min(k, b[j]);dp[i][tmp] = min(dp[i][tmp], dp[i - 1][k] + p[j]);}}}double ans = 0.0;for(int i = 0; i <= maxb; i++){if(dp[n - 1][i] != inf)// (n - 1)p写成n了 弄得答案一直不对 ********** 1ans = max(ans, 1.0 * i / dp[n - 1][i]);}printf("%.3lf\n", ans);// 这里居然一直没把ans写进去搞得一直0.000O…晕… ************ 2}return 0;}



0 0
原创粉丝点击