CF2208C Stamina and Tasks
思路
若选择完成一个任务,则后面的所有收入将会乘以 $\frac{100-p_i}{100}$。
而无论后面如何选择,都不会对前面有影响。
所以我们考虑从后往前枚举,并将第 $i$ 位以及它后面的最大收入设为 $s_i$。
假设当前枚举到了第 $i$ 位,若选择完成这个任务,则 $s_i$ 会变为 $c_i+s_{i+1}\times\frac{100-p_i}{100}$,若不完成,则是继承 $s_{i+1}$。
将这两个值比较后取更大的一个就可以了。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include<bits/stdc++.h> #define fir first #define sec second #define int long long #define double long double #define pii pair<int,int> #define fep(i,s,e) for(int i=s;i<e;i++) #define pef(i,s,e) for(int i=s;i>e;i--) #define rep(i,s,e) for(int i=s;i<=e;i++) #define per(i,s,e) for(int i=s;i>=e;i--) namespace FastIO{ template<typename T>inline void read(T &x){ x=0;int f=1;char c=getchar(); for(;!isdigit(c);c=getchar())if(c=='-')f=-1; for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);x*=f; } template<typename T,typename...Args> inline void read(T &x,Args&...args){ read(x); read(args...); } template<typename T>void print(T x){ if(x<0)x=-x,putchar('-'); if(x>9)print(x/10); putchar((x%10)^48); } } using namespace std; using namespace FastIO; const int N=1e5+7; int T,n,c[N],p[N]; double a[N],s[N]; signed main(){ read(T); while(T--){ read(n); rep(i,1,n){ read(c[i],p[i]); } s[n+1]=0; per(i,n,1){ double P=p[i]/100.0; s[i]=fmax((double)c[i]+s[i+1]*(1.0-P),s[i+1]); } printf("%.7Lf\n", s[1]); } }
|