POJ 1018 Communication System(二维DP)
总结
1. dp[i][j] 第二个变量 j 的设置. j 可以设置成 Money, 也可以是带宽. 分别写一下状态转移方法会发现 j 是带宽时简单些, 并且带宽枚举量少一下
2. dp[i][j] = min(dp[i][j], price[i][k]+dp[i-1][j]) for all k that bw[i][k] >= j
代码 WA. discuss 的测试数据都通过了, 可能是 dp[-1] 的问题, 以后再改吧
/*
* source.cpp
*
* Created on: 2014-4-5
* Author: vincent
*/
/*
* dp[i][j] 前 i 件设备, 最大带宽为 j 时的最小花费
*/
#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <math.h>
using namespace std;
int bw[110][110];
int price[110][110];
int manu[110];
int dp[110][10010];
double cal(int n, int MAXBW) {
memset(dp, 0x3f, sizeof(dp));
for(int i = 0; i < n; i ++) {
for(int j = 0; j <= MAXBW; j ++) {
for(int k = 0; k < manu[i]; k ++) {
if(bw[i][k] < j) continue;
dp[i][j] = min(dp[i][j], dp[i-1][j]+price[i][k]);
}
}
}
double ret = 0.0;
for(int j = 0; j <= MAXBW; j ++) {
ret = max(ret, 1.0*j/dp[n-1][j]);
}
return ret;
}
int main() {
int cases;
int devices;
int n, MAXDW;
freopen("input.txt", "r", stdin);
scanf("%d", &cases);
while(cases --) {
MAXDW = 0;
scanf("%d", &devices);
for(int i = 0; i < devices; i ++) {
scanf("%d", &n);
manu[i] = n;
for(int j = 0; j < n; j ++) {
scanf("%d%d", &bw[i][j], &price[i][j]);
MAXDW = max(MAXDW, bw[i][j]);
}
}
double res = cal(devices, MAXDW);
printf("%.3f\n", res);
}
return 0;
}

浙公网安备 33010602011771号