2019nc#10

题号标题已通过代码题解/讨论通过率团队的状态
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\n",sum);
            return 0;
}
View Code

 

posted @ 2019-08-17 22:52  ckxkexing  阅读(573)  评论(0编辑  收藏  举报