位操作问题的时间复杂度

时间:2018-12-29 13:55:22

标签: c++ algorithm dynamic-programming bitmask

基本上,我试图计算以下解决方案的时间复杂度,我从Bit masking cap problem那里解决了这个问题,并很好地理解了该问题,但是由于递归在循环内进行,因此无法计算时间复杂度 甚至我的教授都不知道该怎么做?

位掩码

有100种不同类型的大写字母,每个小写字母的ID范围从1到100。此外,有“ n”个人分别具有不同数量的大写字母的集合。有一天,所有这些人都决定参加一个戴着帽子的聚会,但看起来很独特,他们决定他们都不会戴着相同类型的帽子。因此,计算一下安排或方式的总数,以使它们都不佩戴相同类型的帽子。

约束:1 <= n <= 10示例:

    // C++ program to find number of ways to wear hats 
    #include<bits/stdc++.h> 
    #define MOD 1000000007 
    using namespace std; 

    // capList[i]'th vector contains the list of persons having a cap with id i 
    // id is between 1 to 100 so we declared an array of 101 vectors as indexing 
    // starts from 0. 
    vector<int> capList[101]; 

    // dp[2^10][101] .. in dp[i][j], i denotes the mask i.e., it tells that 
    // how many and which persons are wearing cap. j denotes the first j caps 
    // used. So, dp[i][j] tells the number ways we assign j caps to mask i 
    // such that none of them wears the same cap 
    int dp[1025][101]; 

    // This is used for base case, it has all the N bits set 
    // so, it tells whether all N persons are wearing a cap. 
    int allmask; 

    // Mask is the set of persons, i is cap-id (OR the 
    // number of caps processed starting from first cap). 
    long long int countWaysUtil(int mask, int i) 
    { 
        // If all persons are wearing a cap so we 
        // are done and this is one way so return 1 
        if (mask == allmask) return 1; 

        // If not everyone is wearing a cap and also there are no more 
        // caps left to process, so there is no way, thus return 0; 
        if (i > 100) return 0; 

        // If we already have solved this subproblem, return the answer. 
        if (dp[mask][i] != -1) return dp[mask][i]; 

        // Ways, when we don't include this cap in our arrangement 
        // or solution set. 
        long long int ways = countWaysUtil(mask, i+1); 

        // size is the total number of persons having cap with id i. 
        int size = capList[i].size(); 

        // So, assign one by one ith cap to all the possible persons 
        // and recur for remaining caps. 
        for (int j = 0; j < size; j++) 
        { 
            // if person capList[i][j] is already wearing a cap so continue as 
            // we cannot assign him this cap 
            if (mask & (1 << capList[i][j])) continue; 

            // Else assign him this cap and recur for remaining caps with 
            // new updated mask vector 
            else ways += countWaysUtil(mask | (1 << capList[i][j]), i+1); 
            ways %= MOD; 
        } 

        // Save the result and return it. 
        return dp[mask][i] = ways; 
    } 

    // Reads n lines from standard input for current test case 
    void countWays(int n) 
    { 
        //----------- READ INPUT -------------------------- 
        string temp, str; 
        int x; 
        getline(cin, str); // to get rid of newline character 
        for (int i=0; i<n; i++) 
        { 
            getline(cin, str); 
            stringstream ss(str); 

            // while there are words in the streamobject ss 
            while (ss >> temp) 
            { 
                stringstream s; 
                s << temp; 
                s >> x; 

                // add the ith person in the list of cap if with id x 
                capList[x].push_back(i); 
            } 
        } 
        //---------------------------------------------------- 

        // All mask is used to check whether all persons 
        // are included or not, set all n bits as 1 
        allmask = (1 << n) - 1; 

        // Initialize all entries in dp as -1 
        memset(dp, -1, sizeof dp); 

        // Call recursive function count ways 
        cout << countWaysUtil(0, 1) << endl; 
    } 

    // Driver Program 
    int main() 
    { 
        int n; // number of persons in every test case 
        cin >> n; 
        countWays(n); 
        return 0; 
    } 

0 个答案:

没有答案