换topcoder

10.29

最近刷leetcode刷的有点膨胀了

点开web Arena做第一题AB,瞬间AC,卧槽我宝刀未老!

点开一个550、卧槽。。

点开一个850、卧槽草草草。。

弄好了Arena 准备起飞

850的题目是 问N个节点(各不相同)的图,有多少有座桥。

今天做了一题,POJ1737

我又用了一种乱七八糟的方法,我也是醉了

#include<iostream>
#include<algorithm>
#include<map>
#include<unordered_map>
#include<vector>
#include<string>
#include<stack>
#include<queue>

using namespace std;

const int MaxN = 50;

int main()
{
    vector<long long> f = vector<long long>(MaxN + 1, 0);
    vector<vector<long long>> g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0));
    vector<vector<long long>> c = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0));

    c[0][0] = 1;
    for (int i = 1; i <= MaxN; i++)
    {
        c[i][0] = c[i][i] = 1;
        for (int j = 1; j <= i-1; j++)
            c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
    }

    //
    g[0][0] = 1;
    //


    f[1] = 1;
    for (int n = 2; n <= MaxN; n++)
    {
        //g[n-1,n-1]
        for (int k = 1; k <= n - 1; k++)
        {
            for (int s1 = 1; s1 <= n - 1; s1++)
                g[n - 1][k] += ((1 << s1) - 1)*f[s1] * c[n - 2][s1 - 1] * g[n - 1 - s1][k - 1];
            f[n] += g[n - 1][k];
        }
    }

    int X;
    while (cin >> X)
    {
        if (!X) break;
        cout << f[X] << endl;
    }

    return 0;
}

这当然是过不了了。。时间复杂度比较高,然后高精度也没有上。

不过意思到了就行了

我想的是 1连的那个连通分支有哪些点,用dp套一个dp

 

看了别人的解答:

设f(n)为所求答案

g(n)为n个顶点的非联通图

则f(n) + g(n) = h(n) = 2^(n * (n - 1) / 2)

其中h(n)是n个顶点的联图的个数

 

这样计算

先考虑1所在的连通分量包含哪些顶点

假设该连通分量有k个顶点

就有C(n - 1, k - 1)种集合

确定点集后,所在的连通分量有f(k)种情况。其他连通分量有 h(n - k)种情况

因此有递推公式。g(n) = sum{ C(n - 1, k - 1) * f(k) * h(n - k)} 其中k = 1,2...n-1

注意每次计算出g(n)后立刻算出f(n)

 

好吧 我那个做法也许是有一些借鉴意义的。。毕竟。。难想到。。

11.8

先贴一个小数据版本的,妈蛋为了搞这个一晚上没有玩多塔

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include<algorithm>
#include<map>
#include<unordered_map>
#include<vector>
#include<string>
#include<stack>
#include<queue>

using namespace std;

const int MaxN = 15;
const long long Modulo = 1000000007;

vector<vector<long long>> calcComb()
{
    vector<vector<long long>> c = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0));
    c[0][0] = 1;
    for (int i = 1; i <= MaxN; i++)
    {
        c[i][0] = c[i][i] = 1;
        for (int j = 1; j <= i - 1; j++)
            c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % Modulo;
    }
    return c;
}

long long pow(int s1, int c)
{
    long long ret = 1;
    while (c--) ret *= s1;
    return ret;
}

int main()
{
    
    auto C = calcComb();

    //calc f1[n] : n nodes with 1 component
    auto f1 = vector<long long>(MaxN + 1, 0);
    auto g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0));
    g[0][0] = 1;
    f1[1] = 1;
    for (int n = 2; n <= MaxN; n++)
    {
        for (int c = 1; c <= n - 1; c++)  // c components
        {
            for (int s1 = 1; s1 <= n - 1; s1++)
                g[n - 1][c] += ((1 << s1) - 1) * f1[s1] * C[n - 2][s1 - 1] * g[n - 1 - s1][c - 1];
            f1[n] += g[n - 1][c];
        }
    }
    //f2[n]: n nodes with no bridge
    auto f2 = vector<long long>(MaxN + 1, 0);
    g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0));
    g[0][0] = 1;
    f2[0] = 1;
    for (int n = 1; n <= MaxN; n++)
    {
        f2[n] = f1[n];
        for (int c = 1; c <=  n - 1; c++)
        {
            for (int s1 = 1; s1 <= n - 1; s1++)
                g[n - 1][c] += (s1 * C[n - 2][s1 - 1] * f1[s1] * g[n - 1 - s1][c - 1]);
        }
        for (int s1 = 1; s1 <= n - 1; s1++)
        {
            for (int c = 1; c <= n - 1;c++)
            f2[n] -= (C[n - 1][s1 - 1] * f2[s1] * /*/ 激动的快哭了,找到个bug的时候,没有乘 /*/pow(s1,c) * g[n - s1][c]);
        }
    }
    
    auto f3 = vector<vector<long long>>(MaxN + 1,vector<long long>(MaxN + 1,0));
    //f3[n][k] n nodes k bridges
    f3[0][0] = 1;
    
    auto gg = vector<vector<vector<long long>>>(MaxN + 1, vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)));
    
    gg[0][0][0] = 1;
    
    for (int n = 1; n <= MaxN; n++)
    {
        f3[n][0] = f2[n];
        for (int k = 1; k <= MaxN; k++)
        {
            for (int c = 1; c <= n - 1;c++)
            for (int n1 = 1; n1 <= n - 1;n1++)
            for (int k1 = 0; k1 < k; k1++)
            {
                gg[n - 1][k][c] += n1 * C[n-2][n1-1] * f3[n1][k1] * gg[n - 1 - n1][k - k1 - 1][c - 1];
            }
            for (int n1 = 1; n1 <= n - 1; n1++)
            {
                for (int c = 1; c <= n; c++)
                    f3[n][k] += C[n - 1][n1 - 1] * f2[n1] * /*还TM漏一个*/pow(n1,c) * gg[n - n1][k][c];
            }
        }
    }

    auto f4 = vector<vector<vector<long long>>>(MaxN + 1, vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)));
    f4[0][0][0] = 1;
    for (int n = 1; n <= MaxN; n++)
    for (int k = 0; k < MaxN; k++)
    {
        f4[n][k][1] = f3[n][k];
        for (int c = 2; c <= MaxN; c++)
        {
            for (int n1 = 1; n1 <= n;n1++)
            for (int k1 = 0; k1 <= k; k1++)
                f4[n][k][c] += f3[n1][k1] * C[n - 1][n1 - 1] * f4[n - n1][k - k1][c-1];
        }
    }

    int n, k;

    while (cin >> n >> k)
    {
        int ret = 0;
        for (int c = 1; c <= n; c++)
        ret += f4[n][k][c];
        cout << ret << endl;
    }

    system("pause");
    return 0;
}

 再来一个超时版本的O(N^5)

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include<algorithm>
#include<map>
#include<unordered_map>
#include<vector>
#include<string>
#include<stack>
#include<queue>

using namespace std;

const int MaxN = 50;
const long long M = 1000000007;

long long mul(long long A, long long B)
{
    return (A % M) * (B % M) % M;
}

void adt(long long& x, long long a)
{
    x = (x + a) % M;
}

vector<vector<long long>> calcComb()
{
    auto c = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0));
    c[0][0] = 1;
    for (int i = 1; i <= MaxN; i++)
    {
        c[i][0] = c[i][i] = 1;
        for (int j = 1; j <= i - 1; j++)
            c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % M;
    }
    return c;
}


vector<vector<long long>> calcPow()
{
    auto p = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0));
    for (int i = 1; i <= MaxN; i++)
    {
        p[i][0] = 1;
        for (int j = 1; j <= MaxN; j++) p[i][j] = mul(i,p[i][j-1]);
    }
    return p;
}

int main()
{
    
    auto C = calcComb();
    auto POW = calcPow();

    //calc f1[n] : n nodes with 1 component
    auto f1 = vector<long long>(MaxN + 1, 0);
    auto g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0));
    g[0][0] = 1;
    f1[1] = 1;
    for (int n = 2; n <= MaxN; n++)
    {
        for (int c = 1; c <= n - 1; c++)  // c components
        {
            for (int s1 = 1; s1 <= n - 1; s1++)
                g[n - 1][c] += mul(mul(mul((pow(2,s1) - 1),f1[s1]),C[n - 2][s1 - 1]),g[n - 1 - s1][c - 1]);
            adt(f1[n],g[n - 1][c]);
        }
    }
    //f2[n]: n nodes with no bridge
    auto f2 = vector<long long>(MaxN + 1, 0);
    g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0));
    g[0][0] = 1;
    f2[0] = 1;
    for (int n = 1; n <= MaxN; n++)
    {
        f2[n] = f1[n];
        for (int c = 1; c <=  n - 1; c++)
        {
            for (int s1 = 1; s1 <= n - 1; s1++)
                adt(g[n - 1][c],mul(mul(mul(s1, C[n - 2][s1 - 1]),f1[s1]),g[n - 1 - s1][c - 1]));
        }
        for (int s1 = 1; s1 <= n - 1; s1++)
        {
            for (int c = 1; c <= n - 1;c++)
            adt(f2[n],M-mul(mul(mul(C[n - 1][s1 - 1],f2[s1]),/*/ 激动的快哭了,找到个bug的时候,没有乘 /*/POW[s1][c]),g[n - s1][c]));
        }
    }
    
    auto f3 = vector<vector<long long>>(MaxN + 1,vector<long long>(MaxN + 1,0));
    //f3[n][k] n nodes k bridges
    f3[0][0] = 1;
    
    auto gg = vector<vector<vector<long long>>>(MaxN + 1, vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)));
    
    gg[0][0][0] = 1;
    
    for (int n = 1; n <= MaxN; n++)
    {
        f3[n][0] = f2[n];
        for (int k = 1; k <= MaxN; k++)
        {
            for (int c = 1; c <= n - 1;c++)
            for (int n1 = 1; n1 <= n - 1;n1++)
            for (int k1 = 0; k1 < k; k1++)
            {
                adt(gg[n - 1][k][c],mul(mul(mul(n1,C[n-2][n1-1]),f3[n1][k1]),gg[n - 1 - n1][k - k1 - 1][c - 1]));
            }
            for (int n1 = 1; n1 <= n - 1; n1++)
            {
                for (int c = 1; c <= n; c++)
                    adt(f3[n][k],mul(mul(mul(C[n - 1][n1 - 1],f2[n1]), /*还TM漏一个*/POW[n1][c]),gg[n - n1][k][c]));
            }
        }
    }

    auto f4 = vector<vector<vector<long long>>>(MaxN + 1, vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)));
    f4[0][0][0] = 1;
    for (int n = 1; n <= MaxN; n++)
    for (int k = 0; k < MaxN; k++)
    {
        f4[n][k][1] = f3[n][k];
        for (int c = 2; c <= MaxN; c++)
        {
            for (int n1 = 1; n1 <= n;n1++)
            for (int k1 = 0; k1 <= k; k1++)
                adt(f4[n][k][c],mul(mul(f3[n1][k1],C[n - 1][n1 - 1]),f4[n - n1][k - k1][c-1]));
        }
    }

    int n, k;

    while (cin >> n >> k)
    {
        long long ret = 0;
        for (int c = 1; c <= n; c++)
        adt(ret,f4[n][k][c]);
        cout << ret << endl;
    }

    system("pause");
    return 0;
}

 

posted @ 2015-10-29 20:12  syb3181  阅读(213)  评论(3编辑  收藏  举报