srm 540

http://mlz000.github.io/2015/07/16/srm-540/

250


Description:

給定 一個數組B,和一個”+-“組成的字符數組,求有多少種A數組。
B數組是由A數組相鄰的兩個數和符號運算後的結果。

Solution

顯然如果第一個數固定,整個A數組就固定下來了,所以就是求第一個數有多少種可能。我們發現給定的是A1+x2A2A3... 這種形式。於是我們可以通過連續的運算得到A1 和其他Ai 的關係,取上下界即可。

Code

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define F first
#define S second
typedef long long LL;
typedef pair<int, int> pii;
vector<LL> B(51);
struct ImportantSequence {
    int getCount(vector <int> b, string operators) {
        int n = b.size();
        for (int i = 0; i < n; ++i) B[i] = b[i];
        LL L = 1, R = 1e18, now = -1, last = 0;
        for (int i = 0; i < n; ++i) {
            if (now == 1)   B[i] = last - B[i];
            else B[i] += last;
            now = (now == 1) ? (operators[i] == '+' ? -1 : 1) : (operators[i] == '+' ? 1 : -1);
            if (now == 1)   R = min(R, (LL)B[i] - 1);
            else L = max(L, (LL)B[i] + 1);
            last = B[i];
        }
        return L > R ? 0 : R - L > 2e9 ? -1 : R - L + 1;
    }
};

550


Description

N 個柵欄按照標號0,1,...,N1 圍成一個圈,從0 號柵欄開始染色。每一種顏色用R,G,B 三原色表示,並且0R<maxR,0G<maxG,0B<maxB 。規定相鄰的兩個柵欄顏色必須符合以下的顏色過渡條件:

  • 兩種顏色的對應R,G,B差值全部都小於等於d2
  • 兩種顏色的對應R,G,B差值至少有一個大於等於d1

0 號柵欄染色爲(startR,startG,startB) , 然後按編號逐一染色,每次選擇顏色時都是考慮前一個柵欄的顏色,隨機等概率從所有符合過渡條件的顏色中挑選。問當完成N1 號柵欄的染色時,N10 之間不符合顏色過渡條件的概率是多少。
數據範圍爲50

Solution

容易想到dp[i][r][g][b],但是暴力轉移的複雜度顯然是不能接受的,接下來很容易想到三維前綴和維護轉移,不妨反向考慮第N1 不合理的情況,看有多少概率最後可以變成初始狀態即可。複雜度O(nmaxRmaxGmaxB)

Code

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define F first
#define S second
typedef long long LL;
typedef pair<int, int> pii;
const int N = 51;
double dp[41][N][N][N], _[N], sum[N][N][N];
struct RandomColoring {
    double getProbability(int n, int maxR, int maxG, int maxB, int startR, int startG, int startB, int d1, int d2) {
        for (int r = 0; r < maxR; ++r)
            for (int g = 0; g < maxG; ++g)
                for (int b = 0; b < maxB; ++b) {
                    int t1 = abs(r - startR), t2 = abs(g - startG), t3 = abs(b - startB);
                    if (!(t1 <= d2 && t2 <= d2 && t3 <= d2 && (t1 >= d1 || t2 >= d1 || t3 >= d1)))  dp[n - 1][r][g][b] = 1.0;
                }
        for (int i = n - 2; i >= 0; --i) {
            for (int r = 1; r <= maxR; ++r)
                for (int g = 1; g <= maxG; ++g)
                    for (int b = 1; b <= maxB; ++b)
                        sum[r][g][b] = dp[i + 1][r - 1][g - 1][b - 1] + sum[r - 1][g][b] + sum[r][g - 1][b] + sum[r][g][b - 1] - sum[r - 1][g - 1][b] - sum[r][g - 1][b - 1] - sum[r - 1][g][b - 1] + sum[r - 1][g - 1][b - 1];
            for (int r = 0; r < maxR; ++r)
                for (int g = 0; g < maxG; ++g)
                    for (int b = 0; b < maxB; ++b) {
                        double &t = dp[i][r][g][b];
                        int r1 = max(r - d2, 0), r2 = min(r + d2 + 1, maxR);
                        int g1 = max(g - d2, 0), g2 = min(g + d2 + 1, maxG);
                        int b1 = max(b - d2, 0), b2 = min(b + d2 + 1, maxB);
                        int tot = (r2 - r1) * (g2 - g1) * (b2 - b1);
                        t = sum[r2][g2][b2] - sum[r1][g2][b2] - sum[r2][g1][b2] - sum[r2][g2][b1] + sum[r1][g1][b2] + sum[r2][g1][b1] + sum[r1][g2][b1] - sum[r1][g1][b1];
                        if (d1) {
                            r1 = max(r - d1 + 1, 0), r2 = min(r + d1, maxR);
                            g1 = max(g - d1 + 1, 0), g2 = min(g + d1, maxG);
                            b1 = max(b - d1 + 1, 0), b2 = min(b + d1, maxB);
                            tot -= (r2 - r1) * (g2 - g1) * (b2 - b1);
                            t -= sum[r2][g2][b2] - sum[r1][g2][b2] - sum[r2][g1][b2] - sum[r2][g2][b1] + sum[r1][g1][b2] + sum[r2][g1][b1] + sum[r1][g2][b1] - sum[r1][g1][b1];
                        }
                        if (tot)    t /= tot;
                    }
        }
        return dp[0][startR][startG][startB];
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章