首页 > 代码库 > HDU 4833 Best Financing (DP)

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。
 

 

Input
第一行为T (T<=200),表示输入数据组数。
每组数据格式如下:
第一行是n m
之后连续n行,每行为两个以空格分隔的整数,依次为date和earning
之后连续m行,每行为三个以空格分隔的整数,依次为start, finish和interest_rate
 

 

Output
对第i组数据,i从1开始计,输出
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
2014年百度之星程序设计大赛 - 初赛(第二轮)
 

 

这个问题主要是进行转化。

 

把投资点进行离散化,就可以看成从每个投资点出发可以最多赚多少钱。

 

每个投资点前面一段是属于这个点的钱。

 

然后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 }