继续学习DP,但是这个题目好像说是枚举更为恰当。到现在还学习这种东西,于是又一顿鄙视自己先。题目来源
题目大意懒得自己写,于是网上摘录了别人翻译的题目大意:产品有n个部分 组成 每个部分有m种选择,每个部件 有bandwith和price两种属性。求:一种选择方案使B/P 最大 其中 B是各个部件bandwith的最小值 P是各个部件price的和。来源
利用枚举带宽(bandwidth),即可通过找到价格(price)最小值和来贪心的找到B/P的最大值。
交了好几次过不去,于是Google了下看别人的测试数据,结果是基本没有。于是再参考了这篇文章,思路大致一致,他的剪枝做得更好,于是修改了下自己的,代码中标记为mark,然后就过了(也许也正是这几个break影响了之前的结果,老是过不去,具体原因不知)。
代码如下:
1: #include <iostream>
2: #include <iomanip>
3: #include <set>
4: using namespace std;
5: const int MAX_SIZE = 100;
6: const int MAX_BRANDWIDTH = (1<<15);
7: const int MAX_PRICE = (1<<15);
8:
9: struct DevNode
10: {
11: int count;
12: int bandwidth[MAX_SIZE];
13: int price[MAX_SIZE];
14: };
15:
16: DevNode dev[MAX_SIZE];
17: int devNum;
18: set<int> band;
19:
20: void getResult()
21: {
22: int totalPrice=0;
23: double maxRatio = 0;
24: int maxPrice=0, minPrice=MAX_PRICE;
25:
26: bool found = false;
27: int bandwidth;
28: for (set<int>::const_iterator p=band.begin(); p!=band.end(); p++)
29: {
30: totalPrice = 0;
31: bandwidth = *p;
32: for (int i=0; i<devNum; i++)
33: {
34: found = false; //mark
35: minPrice = MAX_PRICE;
36: for (int j=0; j<dev[i].count; j++)
37: {
38: if (dev[i].bandwidth[j]>=bandwidth && minPrice>dev[i].price[j])
39: {
40: minPrice = dev[i].price[j];
41: found = true;
42: }
43: }
44: if (found) //mark
45: totalPrice += minPrice;
46: else //mark
47: break;
48: }
49: if (found)
50: {
51: double ratio = (double)bandwidth/(double)totalPrice;
52: maxRatio = maxRatio<ratio ? ratio : maxRatio;
53: }
54: else
55: {
56: break;
57: }
58: }
59: cout.setf(ios::fixed,ios::floatfield);
60: cout << setprecision(3) << maxRatio << endl;
61: }
62:
63: int main()
64: {
65: int testNum=0;
66: cin >> testNum;
67: while (testNum--)
68: {
69: band.clear();
70: cin >> devNum;
71: for (int i=0; i<devNum; i++)
72: {
73: cin >> dev[i].count;
74: for (int j=0; j<dev[i].count; j++)
75: {
76: cin >> dev[i].bandwidth[j] >> dev[i].price[j];
77: band.insert(dev[i].bandwidth[j]);
78: }
79: }
80: getResult();
81: }
82: return 0;
83: }