2014百度之星预赛(第二场)——Best Financing

2014百度之星预赛(第二场)——Best Financing

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个时间点,这些时间点你会得到若干的钱.

然后告诉你m个时间段,以及时间段相应的利率(百分比).

问最后最多能够得到多少钱.

注意事项

首先收益不能用于购买

当天得到钱后当前能够花出去,也就是当天finish的当天可用于购买.

分析

理解题意后,心中会想到这是道DP题.

然后看看每一个时间点得到的钱。貌似他们之间是相互独立的.

实际上看到这个是独立的后,就非常好做了.

对于某个时间点的钱,我们随着时间的向后流动,会遇到一些时间段.

对于遇到的时间段,我们有两个选择:1.买; 2.不买.

买了我们的时间就移动到这个时间段的结束时间,不买了我们的时间移动到下一刻.

最后得到的钱是: 当前钱 * 选择的时间段的利率的和.

建议自己画一个图看看,或者自己心里面想想.

因为我们的目标是是收益最大,也就是是选择的时间段的利率和最大.

这个问题能够轻松的写出状态转移方程:

dp[ i ] = max( dp[i],  dp[j] + rate[i, j]);

当中 dp[ i ] 代表 i 时间点到终于时间的路线上最大的利率和。 dp[i] 的初始值能够是 dp[i + 1], 即不选择以这个时间点開始的时间段.

rate[i, j] 代表有个从 i 到 j 的时间段。且这个时间段的利率是 rate[i, j].

这样我们从后向前扫描一遍就能够预处理全部时间点到终于时间的最大利率.

然后我们用当前时间的钱 乘以 当前时间的最优利率和就是当前的最大利益.

以上分析来自博文:http://tiankonguse.com/record/record.php?id=670

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 100005

using namespace std;

typedef struct Money
{
	int dates;
	int earnings;
}Money;

typedef struct Earn
{
	int start;
	int finish;
	int rate;
}Earn;

bool cmp(const Earn &l,const Earn &r)
{
	return l.start<r.start;
}

int dp[MAX];
Money money[MAX];
Earn earn[MAX];
int n,m,maxtime;
long long ans;

void DP()
{
	memset(dp,0,sizeof(dp));
	m--;
	for(int i=maxtime;i>=0;i--)
	{
		dp[i]=dp[i+1];
		while(m>=0&&i==earn[m].start)
		{
			dp[i]=max(dp[i],dp[earn[m].finish]+earn[m].rate);
			m--;
		}
	}
}

int main(int argc,char *argv[])
{
	int t;
	scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		scanf("%d%d",&n,&m);
		maxtime=0;
		for(int j=0;j<n;j++)
		{
			scanf("%d%d",&money[j].dates,&money[j].earnings);
			maxtime=max(maxtime,money[j].dates);
		}
		for(int k=0;k<m;k++)
		{
			scanf("%d%d%d",&earn[k].start,&earn[k].finish,&earn[k].rate);
			maxtime=max(maxtime,earn[k].finish);
		}
		sort(earn,earn+m,cmp);
		DP();
		ans=0;
		for(int j=0;j<n;j++)
			ans+=money[j].earnings*dp[money[j].dates];
		printf("Case #%d:\n",i);
		printf("%I64d.%02I64d\n",ans/100,ans%100);
	}
	return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-10-29 19:08:01

2014百度之星预赛(第二场)——Best Financing的相关文章

2014百度之星初赛(第二场)——Best Financing

2014百度之星初赛(第二场)--Best Financing Problem Description 小A想通过合理投资银行理财产品达到收益最大化.已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在第dates[i]天小A收入earnings[i]元(0<=i<n).银行推出的理财产品均为周期和收益确定的,可描述为长度为m的三个整数数组start.finish和interest_rates, 若购买理财产品i(0<=i<m),需要

2014百度之星初赛(第二场)——JZP Set

2014百度之星初赛(第二场)--JZP Set Problem Description 一个{1, ..., n}的子集S被称为JZP集,当且仅当对于任意S中的两个数x,y,若(x+y)/2为整数,那么(x+y)/2也属于S. 例如,n=3,S={1,3}不是JZP集,因为(1+3)/2=2不属于S.但是{1,2,3}的其他子集都属于S,所以n=3时有7个JZP集 给定n,求JZP集的个数. Input 第一行为T,表示输入数据组数. 每组数据包含一行整数n. 限制条件 1<=T<=10^5

2014百度之星初赛(第二场)——Chess

2014百度之星初赛(第二场)--Chess Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字路线.也就是说,如果"王"当前在(x,y)点,小度在下一步可以移动到(x+1, y), (x-1, y), (x, y+1), (x, y-1), (x+2, y), (x-2, y), (x, y+2), (x, y-2)

2014百度之星资格赛第二题

Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2560    Accepted Submission(s): 366 Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景.

2014百度之星初赛第一场部分题解

代码太丑就不贴了.,又是一篇无责任民科的题解.. HDU 4828 Grids 看了一下跟卡特兰数差点儿相同就猜了一下,详细为啥我也不知道.. 然后有除法套个逆元.. HDU 4830 pid=4830">Party 发现这个除了叶子节点可能是环,剩下就是一棵树了(假设是单独的环,就用虚拟节点0来连接一下) 剩下就是环状树形dp. . 章鱼图上的树形dp.. . . 类似zoj 3527

hdu 5255 魔法因子 打表 或者 乱搞 百度之星初赛第二场1004

题目链接:点击打开链接 题意:能满足 abcde*x=ebcda的数x称为魔法因子,给定一个数,求它是不是魔法因子,若是把符合条件的数输出. 思路:枚举头尾和位数,头尾固定中间的数字也就固定,可是我不会,晚上或者什么时候有空再写: 但是我会打表吖- 枚举10-1e10,判断是否存在魔法因子. cpp: 打表版 #include <cstdio> #include <iostream> #include <cstring> #include <algorithm&g

2014百度之星第二题Disk Schedule

Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1463    Accepted Submission(s): 189 Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景.磁

2014百度之星资格赛—— Xor Sum(01字典树)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起

2014百度之星资格赛——Disk Schedule

2014百度之星资格赛--Disk Schedule Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景. 磁盘有许多轨道,每个轨道有许多扇区,用于存储数据.当我们想在特定扇区来读取数据时,磁头需要跳转到特定的轨道.具体扇区进行读取操作.为了简单,我们假设磁头可以在某个轨道顺时针或逆时针匀速旋转,旋转一周的时间是360个单位时间.磁头也可以随意移动到某个轨道进行