1. 程式人生 > 其它 >2020-2021 ACM-ICPC Brazil Subregional Programming Contest A. Sticker Album (gym 102861A)

2020-2021 ACM-ICPC Brazil Subregional Programming Contest A. Sticker Album (gym 102861A)

技術標籤:動態規劃

題目:A. Sticker Album
題意大意:買卡包,每包裡有卡片[A,B]張,獲得每個卡片的概率都相同,問買多少卡包能組成N張卡片的期望。

在這裡插入圖片描述

設dp[i]為能組成n-i張卡片的期望卡包的數量。
可以得到轉移方程 d p [ i ] = d p [ i + A ] + 1 + . . . + d p [ i + B ] + 1 B − A + 1 dp[i]=\frac{dp[i+A]+1+...+dp[i+B]+1}{B-A+1} dp[i]=BA+1dp[i+A]+1+...+dp[i+B]+1
由於範圍過大,線性遞推,sum維護dp[i+A]-dp[i+B]的總和可以得出答案。

A可以為0,此時方程右邊也出現了的dp[i],特判移向在進行轉移,之後可理解為1-B的轉移。
dp[N]以及大於N的是0。

#include<bits/stdc++.h>
#define mmp make_pair
#define inf 0x3f3f3f3f
#define llinf 0x7fffffffffffffff
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
typedef double ld;
const ll mod=1e9+7;
const int maxn=3e6+10
; double dp[maxn]; int main() { int N,A,B; scanf("%d %d %d",&N,&A,&B); double sum=0.0; for(int i=N+A;i<=N+B;++i) { dp[i]=0.0; } double fm=(B-A+1)*1.0; dp[N]=0.0; if(A) { for(int i=N-1;i>=0;--i) { dp[i]=(sum)/fm+1.0; sum-
=dp[i+B]; sum+=dp[i+A-1]; } } else { for(int i=N-1;i>=0;--i) { dp[i]=(sum+fm)/(fm-1.0); sum-=dp[i+B]; sum+=dp[i]; } } printf("%.8lf",dp[0]); return 0; }