hdu-4833-Best-Financing(DP)

Best Financing

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 148    Accepted Submission(s): 35


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年百度之星程序设计大赛 - 初赛(第二轮)
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:   4831  4830  4829  4828  4827 
 
思路:

将起点终点离散化,之后用起点做DP

/*************************************************************************
	> File Name: hdu-4833-Best-Financing.cpp
	> Author: nealgavin
	> Mail: [email protected] 
	> Created Time: Mon 26 May 2014 07:28:57 PM CST
 ************************************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
const int mm = 5009;
const int nn = 100003;
class Income{
    public:
    int date;
    int earning;
}salry[mm];

class Contral{
    public:
    int start;
    int finish;
    int interest_rates;
}earn[mm];

int T,n,m;
int f[nn],day_in[nn],all_in[nn];
int dp[mm];
map<int,int>mp;
vector<int>vc[2][mm];

int main()
{
    while(~scanf("%d",&T))
    {
        for(int ca=1;ca<=T;++ca)
        {
            scanf("%d %d",&n,&m);
            memset(day_in,0,sizeof(day_in));
            memset(all_in,0,sizeof(all_in));
            for(int i=0;i<n;++i)
            {
                scanf("%d %d",&salry[i].date,&salry[i].earning);
                all_in[ salry[i].date ] += salry[i].earning;
            }
            for(int i=1;i<nn;++i)
                all_in[i] += all_in[i-1];
            for(int i=0;i<m;++i)
                scanf("%d %d %d",&earn[i].start,&earn[i].finish,&earn[i].interest_rates);
            for(int i=0;i<m;++i)
            for(int i=0;i<m;++i)
            {
                f[i] = earn[i].start;
                f[i+m] = earn[i].finish;
            }
            sort(f,f+m+m);
            int pos = unique(f,f+m+m)-f;
            mp.clear();
            for(int i=0;i<pos;++i)
                mp[ f[i] ] = i;
            day_in[ 0 ] = all_in[ f[0] ];
            for(int i=1;i<pos;++i)
                day_in[ i ] = all_in[ f[i] ] - all_in[ f[i-1] ];

            for(int i=0;i<2;++i)
            for(int j=0;j<pos;++j)
                 vc[i][j].clear();
            
            for(int i=0;i<m;++i)
            {
                earn[i].start = mp[ earn[i].start ];
                earn[i].finish = mp[ earn[i].finish ];
                vc[0][ earn[i].start ].push_back(earn[i].finish);
                vc[1][ earn[i].start ].push_back(earn[i].interest_rates);
            }
            memset(dp,0,sizeof(dp));
            for(int i=pos-1;i>=0;--i)
            { 
                dp[i] = dp[i+1];
                int sz = vc[0][i].size();
                for(int j=0;j<sz;++j)
                {
                    dp[i] = max(dp[i],dp[ vc[0][i][j] ]+vc[1][i][j]);
//                    cerr<<"in"<<i<<" "<<dp[i]<<" "<<vc[0][i][j]<<" "<<vc[1][i][j]<<endl;
                }
            }
            long long ans = 0;
            for(int i=0;i<pos;++i)
                ans += (long long)dp[i]*day_in[i];
            printf("Case #%d:\n",ca);
            printf("%.2f\n",(double)ans/100);
        }
    }
    return 0;
}





你可能感兴趣的:(hdu-4833-Best-Financing(DP))