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;
}
时间: 2024-12-28 21:37:06

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,表示在第dat

HDOJ 题目4833 Best Financing(DP)

Best Financing Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 496    Accepted Submission(s): 155 Problem Description 小A想通过合理投资银行理财产品达到收益最大化.已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在

HDU 4745 Two Rabbits(DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4745 题意:n个数排成一个环.两个人AB初始时各自选定一个位置.每一轮A在顺时针方向选择一个位置,B在逆时针选择一个位置,且这两个人所选位置的数字相等,然后格子跳到新选的位置上.问最多进行多少轮?有一个限制为每次跳跃不能跨过以前自己曾经选过的格子. 思路:主要是分析问题的本质.其实就是求最长回文子列.f[i][j]为[i,j]的最长回文子列,则答案为max(f[1][i],f[i+1][n]). i

HDU 1260:Tickets(DP)

Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 923    Accepted Submission(s): 467 Problem Description Jesus, what a great movie! Thousands of people are rushing to the cinema. However,

hdu 1421 搬寝室 (dp)

思路分析: dp[i][j] 表示选取到第 i 个   组成了 j 对的最优答案. 当然排序之后 选取相邻两个是更优的. if(i==j*2) dp[i][j] = dp[i-2][j-1] + w[i]-w[i-2]^2.. else if( i> j*2 ) dp[i][j] = min (dp[i-2][j-1] + ...^2   ,    dp[i-1][j]).... #include <cstdio> #include <iostream> #include &

HDU 1159——Common Subsequence(DP)

Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 23279    Accepted Submission(s): 10242 Problem Description A subsequence of a given sequence is the given sequence with some e

HDU 3237 Help Bubu(DP)

题目链接:点击打开链接 思路: 比赛时查一点出, 需要加一个优化才能防止超时(恶心), 状态很容易想到: d[i][j][s][k]表示前i本书拿了j本没拿的书的集合是s没拿的书的最后一本是k的最优解. 为什么状态压缩的是目前桌子上的书的集合呢?  因为我们要防止一种情况:那就是如果对于高度为H的一种书, 我们都拿走了, 那么还要放回桌子上, 最优解要+1, 这样表示之后, 我们只要判断一下有几种书桌子上没有就行了. 细节参见代码: #include <cstdio> #include <

HDU 5791:Two(DP)

http://acm.hdu.edu.cn/showproblem.php?pid=5791 Two Problem Description Alice gets two sequences A and B. A easy problem comes. How many pair of sequence A' and sequence B' are same. For example, {1,2} and {1,2} are same. {1,2,4} and {1,4,2} are not s

hdu 1176 免费馅饼(DP)

题意: 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内.馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接.但由于小径两侧都不能站人,所以他只能在小径上接.由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼. 为了使问题简化,假设在接下来的一段时间

hdu 2189 来生一起走(DP)

题意: 有N个志愿者.指挥部需要将他们分成若干组,但要求每个组的人数必须为素数.问不同的方案总共有多少.(N个志愿者无差别,即每个组的惟一标识是:人数) 思路: 假设N个人可分为K组,将这K组的人数从小到大排序,num1,...,numk. 故N个人分组的方案数dp[n]=sum(dp[numk]) (所有分为K组的不同方案的和) 代码: bool yes[155]; int prime[155]; int dp[155]; int main(){ mem(yes,true); int C =