Best Financing
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 537 Accepted Submission(s): 171
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#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #define ll long long #define N 100010 using namespace std; int a[N]; int head[N],cnt; struct zz { int u; int v; int w; int next; }edge[N]; void add(int u,int v,int w) { edge[cnt].u=u; edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } double dp[N]; int main() { int t,n,m,T=1; int i,j,k; scanf("%d",&t); while(t--) { cnt=0; memset(head,-1,sizeof(head)); memset(a,0,sizeof(a)); scanf("%d%d",&n,&m); for(i=0;i<n;i++) { int d,e; scanf("%d%d",&d,&e); a[d]+=e; } for(i=0;i<m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } memset(dp,0,sizeof(dp)); double ans=0; printf("Case #\%d:\n",T++); for(i=100000;i>0;i--) { dp[i]=dp[i+1]; for(j=head[i];j!=-1;j=edge[j].next) { dp[i]=max(dp[i],dp[edge[j].v]+edge[j].w); } ans+=dp[i]*a[i]; } printf("%.2lf\n",ans/100); } return 0; }