hdu4833 Best Financing(DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4833
这道题目关键的思想是从后往前dp,dp[i]表示在第i处投资xi能获得的最大收益,其中xi表示从第i-1到第i处投资之间的收入总和(不包括收益),也就是用xi这些钱从第i处开始投资到最后靠xi这些钱获得的最大收益。那么获得的总收益就是dp[0] * x0 + dp[1] * x1 + ... + dp[n] * xn。另一个关键思想就是对理财产品的起始和结束时间进行离散化,这样能够节约空间和dp的时间。
1 #include <stdio.h> 2 #include <vector> 3 #include <map> 4 #include <string.h> 5 #include <algorithm> 6 using namespace std; 7 8 int dates[100005], ls[2505 * 2], jg[2505 * 2]; 9 long long dp[2505 * 2], ans; 10 struct Product 11 { 12 int start, finish, rate; 13 }product[2505]; 14 map<int, int> myMap; 15 vector<int> vec1[2505 * 2], vec2[2505 * 2]; 16 17 #define max(a, b) ((a) > (b) ? (a) : (b)) 18 19 int main(void) 20 { 21 int n, m, t, i, j, k, date, earning, cnt, maxDate; 22 23 scanf("%d", &t); 24 for (i = 1; i <= t; i++) 25 { 26 scanf("%d%d", &n, &m); 27 memset(dates, 0, sizeof(dates)); 28 maxDate = 0; 29 for (j = 0; j < n; j++) 30 { 31 scanf("%d%d", &date, &earning); 32 dates[date] += earning; 33 if (date > maxDate) 34 maxDate = date; 35 } 36 for (j = 0; j < m; j++) 37 { 38 scanf("%d%d%d", &product[j].start, &product[j].finish, &product[j].rate); 39 ls[j] = product[j].start; 40 ls[j + m] = product[j].finish; 41 if (product[j].finish > maxDate) 42 maxDate = product[j].finish; 43 } 44 for (j = 1; j <= maxDate; j++) 45 dates[j] += dates[j - 1]; 46 sort(ls, ls + m + m, less<int>()); 47 cnt = unique(ls, ls + m + m) - ls; 48 jg[0] = dates[ls[0]]; 49 myMap.clear(); 50 for (j = 0; j < cnt; j++) 51 { 52 myMap[ls[j]] = j; 53 jg[j] = dates[ls[j]] - dates[ls[j - 1]]; 54 vec1[j].clear(); 55 vec2[j].clear(); 56 } 57 for (j = 0; j < m; j++) 58 { 59 vec1[myMap[product[j].start]].push_back(myMap[product[j].finish]); 60 vec2[myMap[product[j].start]].push_back(product[j].rate); 61 } 62 memset(dp, 0, sizeof(dp)); 63 for (j = cnt - 1; j >= 0; j--) 64 { 65 dp[j] = dp[j + 1]; 66 for (k = 0; k < vec1[j].size(); k++) 67 dp[j] = max(dp[j], dp[vec1[j][k]] + vec2[j][k]); 68 } 69 ans = 0; 70 for (j = 0; j < cnt; j++) 71 ans += dp[j] * jg[j]; 72 printf("Case #%d:\n%.2lf\n", i, (double)ans / 100.0); 73 } 74 return 0; 75 }