poj1018(动规)

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);
						}
				}

			}

		}
	}
	
	
	
	
}

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

字江慕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值