問題描述
你駕駛着一臺帶有鑽頭(初始能力值w)的飛船,按既定路線依次飛過n個星球。
星球籠統的分爲2類:資源型和維修型。(p爲鑽頭當前能力值)
資源型:含礦物質量a[i],若選擇開採,則得到a[i]p的金錢,之後鑽頭損耗k%,即p=p(1-0.01k)
維修型:維護費用b[i],若選擇維修,則支付b[i]p的金錢,之後鑽頭修復c%,即p=p(1+0.01c)
注:維修後鑽頭的能力值可以超過初始值(你可以認爲是翻修+升級)請作爲艦長的你仔細抉擇以最大化收入。
輸入格式
第一行4個整數n,k,c,w。
以下n行,每行2個整數type,x。
type爲1則代表其爲資源型星球,x爲其礦物質含量a[i];
type爲2則代表其爲維修型星球,x爲其維護費用b[i];
輸出格式
一個實數(保留2位小數),表示最大的收入。
樣例輸入
5 50 50 10
1 10
1 20
2 10
2 20
1 30
樣例輸出
375.00
數據範圍
對於30%的數據 n<=100
另有20%的數據 n<=1000;k=100
對於100%的數據 n<=100000; 0<=k,c,w,a[i],b[i]<=100;保證答案不超過10^9
首先說一下
定義
其中
然而這樣只能得30分。考慮
事實上,這道題的正解有點費用提前計算的感覺。其實也是一個常見的思路:如果正着討論不夠優秀或者難以討論,考慮倒着討論。注意到如果把答案列式計算下來,可以發現一個乘法分配率的形式,因爲每次操作對
最後的答案就是
#include<stdio.h>
#include<algorithm>
#define MAXN 100005
using namespace std;
int N,ty[MAXN];
double K,C,W,v[MAXN],f[MAXN];
int main()
{
int i;
scanf("%d%lf%lf%lf",&N,&K,&C,&W);
for(i=1;i<=N;i++)scanf("%d%lf",&ty[i],&v[i]);
for(i=N;i>=1;i--)
{
if(ty[i]==1)f[i]=max(f[i+1],f[i+1]*(1-K/100)+v[i]);
else f[i]=max(f[i+1],f[i+1]*(1+C/100)-v[i]);
}
printf("%.2lf",W*f[1]);
}