某岛

… : "…アッカリ~ン . .. . " .. .
July 4, 2012

SRM 548

Brief description:

Problem 250. KingdomAndTrees
给定一个数列,要求修复成递增序列。。(所有项都是正数。。。
。定义修复代价为变动最大的数字改变了多少。。求最小修复代价。。。

Problem 450. KingdomAndDice
给定两块骰子。。数字选自 {1, x} 。。
其中一块骰子上的数字已经全部确定。。另一块骰子部分确定。。
。。先要求确定剩下的数字。。使得该游戏尽可能公平。

Problem 1000. KingdomAndCities
计数:求 n 个顶点、m 条边、其中前 k 个顶点恰好连 2 条边时形成连通图的方案数。
( n, m <= 50, k <= 2 .. .

Analysis:

Problem 250. KingdomAndTrees
。。。枚举 i, j 对每对 i, j 更新一下上界。
。(如果出现 Ai <= 1 则锁定其为 1 。。重新更新上界。。。 。(好像也可以二分答案贪心。。 Problem 450. KingdomAndDice 。。。略) 裸 O(n5) 多重背包。。。 dp[i][j] 表示当前使用了 i 个物品,能否得到和等于 j 的方案。 Problem 1000. KingdomAndCities 。。。( 移步。。。

class KingdomAndTrees {
public:
	int minLevel(vector <int> A) {

		int n = SZ(A), res = 0;

		REP(i, n) FOR(j, i+1, n){
		    int t = (j - i + A[i] - A[j] + 1) / 2;
		    if (A[i] - t > 0) checkMax(res, t);
		    else checkMax(res, j - i - A[j] + 1);
		}

		return res;
	}
};
.. .
const int N = 59, M = N * N;

bool dp[N][M]; int cnt[N];
int n, m, s, nn, b;

class KingdomAndDice {
public:
	double newFairness(vector <int> A, vector <int> B, int X) {

	    n = SZ(A); s = n * n; m = s / 2, nn = 0, b = 0;

	    SRT(B), RST(cnt);
	    DWN(i, n, 0) if (A[i] == 0){
            ++nn;
	    }
	    else {
	        int t = lower_bound(ALL(B), A[i]) - B.begin();
            --cnt[t], b += t;
	    }

        cnt[0] = nn; REP(i, n){
            if (i == n - 1) cnt[i+1] = min(nn, cnt[i+1] + max(0, X - B[i]));
            else cnt[i+1] = min(nn, cnt[i+1] + max(0, B[i+1] - B[i] - 1));
        }

        RST(dp), dp[0][b] = true;

        REP(ii, n+1) REP(j, cnt[ii]){
            DWN(i, nn, 0) DWN_1(j, s-ii, b){
                if (dp[i][j]) dp[i+1][j + ii] = true;
            }
        }


        if (dp[nn][m]) return (DB) m / s;

        if (!(s&1)){
            REP(i, M){
                if (m-i>=0 && dp[nn][m-i]) return (DB) (m - i) / s;
                if (m+i<=s && dp[nn][m+i]) return (DB) (m + i) / s;
            }
        }
        else {
            REP(i, M){
                if (m+i<=s && dp[nn][m+i]) return (DB) (m + i) / s;
                if (m-i>=0 && dp[nn][m-i]) return (DB) (m - i) / s;
            }
        }
	}
};
.. .
const int N = 59;

int C[N*(N-1)/2+1][N], S[N][N], A[N][N];
int n, m, k;


int f0(int n, int m){
    return A[n][m];
}

int f1(int n, int m){
    int res = 0; --n, m -= 2;
    FOR(i, 1, n) FOR_1(j, 0, m)
        INC(res, pdt(i, n-i, C[n][i], f0(n-i, m-j), f0(i, j)));
    DIV(res, 2); INC(res, pdt(C[n][2], f0(n, m)));
    return res;
}

int f1_(int n, int m){
    int res = 0; --n, m -= 2;
    FOR(i, 1, n) FOR_1(j, 0, m)
        INC(res, pdt(i, n-i, C[n][i], f0(n-i, m-j), f0(i, j)));
    INC(res, pdt(sqr_M(C[n][1]), f0(n, m)));
    return res;
}

int f2(int n, int m){

    int res = f1_(n-1, m-1); n -= 2, m -= 4;
    INC(res, pdt(sqr_M(C[n][2]), f0(n, m)));

    FOR(i, 1, n) FOR_1(j, 0, m){
        INC(res, pdt(_I(2), sqr_M(i), sqr_M(n-i), C[n][i], f0(n-i, m-j), f0(i, j)));
        INC(res, pdt(i, n-i, C[n][i], sum(C[n-i][2], C[i][2]), f0(n-i, m-j), f0(i, j)));
    }

    #define i3 n-i1-i2
    #define j3 m-j1-j2

    FOR(i1, 0, n) FOR_1(j1, 0, m)
        FOR(i2, 0, n-i1+1) FOR_1(j2, 0, m-j1)
            INC(res, pdt(i1, sqr_M(i2), i3 , C[n][i1], C[n-i1][i2], f0(i3, j3), f0(i2, j2), f0(i1, j1)));

    return res;
}


int f(int n, int m, int k){
    if (k == 0) return f0(n, m);
    else if (k == 1) return f1(n, m);
    else return f2(n, m);
}

class KingdomAndCities {
public:
	int howMany(int n, int k, int m) {

	    ::n = n, ::m = m, ::k = k;

        FOR_1_C(i, 0, max(n, n*(n-1)/2)){
            C[i][0] = 1;REP_C(j, min(max(2, m), i)) C[i][j+1] = sum(C[i-1][j+1], C[i-1][j]);
        }

	    S[0][0] = A[0][0] = 1; REP_1(i, n) FOR_1_C(j, 0, min(m, C[i][2])){
            A[i][j] = S[i][j] = C[C[i][2]][j];
            FOR(ii, 1, i) FOR_1(jj, 0, j) DEC(A[i][j], pdt(C[i-1][ii-1], A[ii][jj], S[i-ii][j-jj]));
	    }

        return f(n, m, k);
	}
};

External link:

http://community.topcoder.com/stat?c=coder_room_stats&rd=15170&cr=22727863