http://poj.org/problem?id=1018
题意:
某公司要建立一套通信系统,该通信系统需要n种设备,而每种设备分别可以有m1、m2、m3、...、mn个厂家提供生产,而每个厂家生产的同种设备都会存在两个方面的差别:带宽bandwidths 和 价格prices。
现在每种设备都各需要1个,考虑到性价比问题,要求所挑选出来的n件设备,要使得B/P最大。
其中B为这n件设备的带宽的最小值,P为这n件设备的总价。
思路:DP解决。
d[i][j]代表选择第i个设备时最小带宽j时的价格。
状态转移方程就是d[i][j]=min{d[i-1][k]+p,d[i][j]}。
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<iomanip> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 100 + 5; int n,m; int dp[maxn][12000]; int main() { //freopen("D:\\txt.txt", "r", stdin); int t, b, p; cin >> t; while (t--) { memset(dp, INF, sizeof(dp)); cin >> n; for (int i = 0; i < n; i++) { cin >> m; for (int j = 0; j < m; j++) { cin >> b >> p; if (i == 0) dp[i][b] = p; else { for (int k = 0; k < 1100; k++) { if (dp[i - 1][k] != INF) { if (k <= b) dp[i][k] = min(dp[i - 1][k] + p, dp[i][k]); else dp[i][b] = min(dp[i - 1][k] + p, dp[i][b]); } } } } } double ans = 0; for (int k = 0; k < 1100; k++) { if (dp[n - 1][k] != INF) { double c = (double)k / dp[n - 1][k]; if (c>ans) ans = c; } } cout << setiosflags(ios::fixed) << setprecision(3) << ans << endl; } return 0; }