HDU 4833 Best Financing (DP)
Best Financing
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 29 Accepted Submission(s): 3
Problem Description
小A想通过合理投资银行理财产品达到收益最大化。已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在第dates[i]天小A收入earnings[i]元(0<=i<n)。银行推出的理财产品均为周期和收益确定的,可描述为长度为m的三个整数数组start、finish和interest_rates, 若购买理财产品i(0<=i<m),需要在第start[i]天投入本金,在第finish[i]天可取回本金和收益,在这期间本金和收益都无法取回,收益为本金*interest_rates[i]/100.0。当天取得的收入或理财产品到期取回的本金当天即可购买理财产品(注意:不考虑复利,即购买理财产品获得的收益不能用于购买后续的理财产品)。假定闲置的钱没有其他收益,如活期收益等,所有收益只能通过购买这些理财产品获得。求小A可以获得的最大收益。
限制条件:
1<=n<=2500
1<=m<=2500
对于任意i(0<=i<n),1<=dates[i]<=100000,1<=earnings[i]<=100000, dates中无重复元素。
对于任意i(0<=i<m),1<=start[i]<finish[i]<=100000, 1<=interest_rates[i]<=100。
限制条件:
1<=n<=2500
1<=m<=2500
对于任意i(0<=i<n),1<=dates[i]<=100000,1<=earnings[i]<=100000, dates中无重复元素。
对于任意i(0<=i<m),1<=start[i]<finish[i]<=100000, 1<=interest_rates[i]<=100。
Input
第一行为T (T<=200),表示输入数据组数。
每组数据格式如下:
第一行是n m
之后连续n行,每行为两个以空格分隔的整数,依次为date和earning
之后连续m行,每行为三个以空格分隔的整数,依次为start, finish和interest_rate
每组数据格式如下:
第一行是n m
之后连续n行,每行为两个以空格分隔的整数,依次为date和earning
之后连续m行,每行为三个以空格分隔的整数,依次为start, finish和interest_rate
Output
对第i组数据,i从1开始计,输出
Case #i:
收益数值,保留小数点后两位,四舍五入。
Case #i:
收益数值,保留小数点后两位,四舍五入。
Sample Input
2
1 2
1 10000
1 100 5
50 200 10
2 2
1 10000
5 20000
1 5 6
5 9 7
Sample Output
Case #1:
1000.00
Case #2:
2700.00
Source
这个问题主要是进行转化。
把投资点进行离散化,就可以看成从每个投资点出发可以最多赚多少钱。
每个投资点前面一段是属于这个点的钱。
然后n^2的DP进行处理。
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2014/5/25 16:13:32 4 File Name :E:\2014ACM\比赛\百度之星初赛2\C.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 struct NN1 21 { 22 int d,e; 23 void input() 24 { 25 scanf("%d%d",&d,&e); 26 } 27 }node1[3000]; 28 struct NN2 29 { 30 int start,finish; 31 int r; 32 void input() 33 { 34 scanf("%d%d%d",&start,&finish,&r); 35 } 36 }node2[3000]; 37 int a[5010]; 38 long long f[100010]; 39 long long f2[5010]; 40 int dp[5010]; 41 42 vector<int>vec[5010]; 43 vector<int>vec2[5010]; 44 int main() 45 { 46 //freopen("in.txt","r",stdin); 47 //freopen("out.txt","w",stdout); 48 int T; 49 int iCase = 0; 50 int n,m; 51 scanf("%d",&T); 52 while(T--) 53 { 54 iCase++; 55 printf("Case #%d:\n",iCase); 56 scanf("%d%d",&n,&m); 57 int cnt = 0; 58 memset(f,0,sizeof(f)); 59 for(int i = 0;i < n;i++) 60 { 61 node1[i].input(); 62 //a[cnt++] = node1[i].d; 63 f[node1[i].d] += node1[i].e; 64 } 65 for(int i = 1;i <= 100000;i++) 66 f[i] += f[i-1]; 67 for(int i = 0;i < m;i++) 68 { 69 node2[i].input(); 70 a[cnt++] = node2[i].start; 71 a[cnt++] = node2[i].finish; 72 } 73 sort(a,a+cnt); 74 cnt = unique(a,a+cnt) - a; 75 map<int,int>mp; 76 for(int i = 0;i < cnt;i++) 77 mp[a[i]] = i; 78 f2[0] = f[a[0]]; 79 for(int i = 1;i < cnt;i++) 80 f2[i] = f[a[i]] - f[a[i-1]]; 81 for(int i = 0;i < cnt;i++) 82 { 83 vec[i].clear(); 84 vec2[i].clear(); 85 } 86 for(int i = 0;i < m;i++) 87 { 88 node2[i].start = mp[node2[i].start]; 89 node2[i].finish = mp[node2[i].finish]; 90 vec[node2[i].start].push_back(node2[i].finish); 91 vec2[node2[i].start].push_back(node2[i].r); 92 } 93 memset(dp,0,sizeof(dp)); 94 for(int i = cnt-1;i >= 0;i--) 95 { 96 dp[i] = dp[i+1]; 97 int sz = vec[i].size(); 98 for(int j = 0;j < sz;j++) 99 dp[i] = max(dp[i],dp[vec[i][j]] + vec2[i][j]); 100 } 101 long long ans ; 102 //minCostMaxflow(cnt,cnt+1,ans); 103 ans = 0; 104 for(int i = 0;i < cnt;i++) 105 { 106 ans += (long long)dp[i]*f2[i]; 107 } 108 printf("%.2lf\n",(double)ans/100); 109 110 } 111 return 0; 112 }
人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想