题号 | 标题 | 已通过代码 | 题解/讨论 | 通过率 | 团队的状态 |
---|---|---|---|---|---|
A | Blackjack | 点击查看 | 背包DP | 32/109 | 补好了 |
B | Coffee Chicken | 点击查看 | 进入讨论 | 738/2992 | 通过 |
C | Gifted Composer | 点击查看 | 哈希 | 12/64 | 未通过 |
D | Han Xin and His Troops | 点击查看 | 进入讨论 | 602/4072 | 通过 |
E | Hilbert Sort | 点击查看 | 进入讨论 | 508/1681 | 通过 |
F | Popping Balloons | 点击查看 | 进入讨论 | 236/920 | 通过 |
G | Road Construction | 点击查看 | 进入讨论 | 65/638 | 通过 |
H | Stammering Chemists | 点击查看 | 进入讨论 | 810/1595 | 通过 |
I | Travel Dream | 点击查看 | 进入讨论 | 1/191 | 未通过 |
J | Wood Processing | 点击查看 | 进入讨论 | 169/1204 | 通过 |
A Blackjack
题意:
牌堆里有n($n <= 500$)张牌, 每张牌都有一个值,你顺序从牌堆里抽牌,当手中的牌的值和在$(a, b]$时,可以胜利,没有出现就是失败。
现在随机打乱牌堆里的牌的顺序,问获胜的概率。
思路:
枚举以每个点为结尾获胜的情况。
用$dp[i][j] $ 表示取$i$个,$sum$为$j$的方案数。
每次操作的时候,去掉枚举的那个的影响,数出合法个数。
#include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <stack> #include <cmath> #include <queue> #include <list> #include <map> #include <set> #include <cassert> #include <unordered_map> // #include<bits/extc++.h> // using namespace __gnu_pbds; using namespace std; #define pb push_back #define fi first #define se second #define debug(x) cerr<<#x << " := " << x << endl; #define bug cerr<<"-----------------------"<<endl; #define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; template<typename T> inline T read(T&x){ x=0;int f=0;char ch=getchar(); while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x=f?-x:x; } /**********showtime************/ const int maxn = 509; int val[maxn]; ld dp[maxn][maxn]; ld fac[maxn]; int n,a,b; void add(int v) { for(int i=n; i>=1; i--) { for(int j=v; j<=b; j++){ dp[i][j] += dp[i-1][j - v]; } } } void sub(int v) { for(int i=1; i<=n; i++) { for(int j=v; j<=b; j++){ dp[i][j] -= dp[i-1][j - v]; } } } int main(){ scanf("%d%d%d", &n, &a, &b); for(int i=1; i<=n; i++) scanf("%d", &val[i]); fac[0] = 1; for(int i=1; i<=n; i++) fac[i] = fac[i-1] * i; dp[0][0] = 1; for(int i=1; i<=n; i++) add(val[i]); ld sum = 0; for(int i=1; i<=n; i++) { sub(val[i]); for(int j = 0; j<n; j++) { for(int k = max(0, a-val[i] + 1); k <= min(a, b-val[i]); k++) { sum += dp[j][k] * fac[j] * fac[n - j - 1]; } } add(val[i]); } sum = sum / fac[n]; printf("%.12Lf ",sum); return 0; }