poj1018:http://poj.org/problem?id=1018
通过此题,我学到:
1.该题目给出了设备种类的范围,没给出设备带宽的范围,因为它是个离散量,打表尝试,500可以,400报错
2.dp[ ][ ],行标表示设备号,列标表示带宽号,值表示最小价格,第一行要初始化
对于每一个设备i的当前厂商给出的带宽b和价格p,要搜索之前的i-1个设备的所有带宽,比较:
2.1若当前带宽b≤已有带宽k,则更新表中的当前带宽列对应值dp[i][p],取min{dp[i][p],dp[i-1][k]+p}
2.2若当前带宽b>已有带宽k,则更新表中已有带宽的对应值dp[i][k],取min{dp[i][k],dp[i-1][k]+p}
java代码:
import java.util.Scanner;
public class Main{
static int t, n;
static int[][] dp = new int[101][500];// 行表示设备号,列表示带宽,其值表示最小价值和
static Scanner scanner;
public static void main(String[] args) {
scanner = new Scanner(System.in);
t = scanner.nextInt();// t种测试用例
for (int i = 1; i <= t; i++) {
n = scanner.nextInt();// n种设备,对应dp表n行
init();// 初始化dp表
sol();//解决问题
System.out.printf("%.3f\n",find());//找到最大值并输出
}
scanner.close();
}
static void init() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < 500; j++) {
dp[i][j] = Integer.MAX_VALUE;
}
}
}
static double find() {
double max=0;
for(int j=0;j<500;j++) {
if(dp[n-1][j]!=Integer.MAX_VALUE&&(double)j/dp[n-1][j]>max) {
max=(double)j/dp[n-1][j];
}
}
return max;
}
static void sol() {
for (int i = 0; i < n; i++) {// 对于dp表的每一行
int m = scanner.nextInt();// 表示输入的该行有m对
for (int j = 0; j < m; j++) {//对于每一个厂商
int b = scanner.nextInt();// 第j厂商的row设备的带宽
int p = scanner.nextInt();// 第j厂商的row设备的价格
if (i == 0) dp[i][b] = Math.min(dp[i][b], p);
else {
for (int k = 0; k < 500; k++)
if (dp[i - 1][k] != Integer.MAX_VALUE) {// 找到前面设备的所有带宽
if (k <= b) // 若该带宽小于新设备带宽
dp[i][k] = Math.min(dp[i][k], dp[i - 1][k] + p);
else
dp[i][b] = Math.min(dp[i][b], dp[i - 1][k] + p);
}
}
}
}
}
}