ZOJ 3777 - Problem Arrangement - [Shape Pressure DP][The 11th Zhejiang Provincial Competition B Question]

Topic link: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777

Time Limit: 2 Seconds      Memory Limit: 65536 KB

The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward is going to arrange the order of the problems. As we know, the arrangement will have a great effect on the result of the contest. For example, it will take more time to finish the first problem if the easiest problem hides in the middle of the problem list.

There are N problems in the contest. Certainly, it's not interesting if the problems are sorted in the order of increasing difficulty. Edward decides to arrange the problems in a different way. After a careful study, he found out that the i-th problem placed in the j-th position will add Pij points of "interesting value" to the contest.

Edward wrote a program which can generate a random permutation of the problems. If the total interesting value of a permutation is larger than or equal to M points, the permutation is acceptable. Edward wants to know the expected times of generation needed to obtain the first acceptable permutation.

Input

There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

The first line contains two integers N (1 <= N <= 12) and M (1 <= M <= 500).

The next N lines, each line contains N integers. The j-th integer in the i-th line is Pij (0 <= Pij <= 100).

Output

For each test case, output the expected times in the form of irreducible fraction. An irreducible fraction is a fraction in which the numerator and denominator are positive integers and have no other common divisors than 1. If it is impossible to get an acceptable permutation, output "No solution" instead.

Sample Input

2
3 10
2 4 1
3 2 2
4 5 3
2 6
1 3
2 4

Sample Output

3/1
No solution

 

Title:

There are n questions, from easy to difficult, if the i-th difficult question is placed in the j-th position, the "interesting degree" of P[i][j] will be generated;

Now there is a program that randomly generates the arrangement of these n topics. If the sum of the interestingness of all the topics in an arrangement is greater than or equal to m, it is considered to meet the requirements;

Find the expected number of times to produce a permutation of items that satisfies the requirement.

 

answer:

State pressure DP method: state is an n-bit binary number, each 1 or 0 represents whether the position is occupied;

Suppose dp[state][k] represents: the placement of the first i questions is arranged according to the state, resulting in the number of solutions with an interesting degree of k;

State transfer:

  If you want to calculate the value of dp[state][k] when the cnt topics are arranged by state (all solutions with interest degree k>m are counted in k=m), then:

  Remove a question from state, assuming that the question placed in the i-th position is removed, and get new_state (this new_state must be smaller than state),

  Then enumerate k=0~m, dp[state][(k+p[cnt][i])] += dp[new_state][k], also remember to count all the solutions with interesting degree k>m k=m.

Correctness:

When state=0, that is, the initial dp[0][0] is 1, and dp[0][1~m] is 0, which is correct, so the state transition can be started from state=1;

At the same time, as mentioned above, new_state must be smaller than state. We enumerate state from small to large, then all new_state must have been calculated when calculating state.

 

AC code:

#include<bits/stdc++.h>
using namespace std;

int n,m;
int p[15][15];
int dp[1<<12][1300];

inline int gcd(int m,int n){return n?gcd(n,m%n):m;}

int fact[15];
void calcfact()
{
    fact[0]=1;
    for(int i=1;i<=12;i++) fact[i]=fact[i-1]*i;
}

intmain ()
{
    calcfact();

    int t;
    scanf("%d",&t);
    memset(p,0,sizeof(p));
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&p[i][j]);

        memset(dp,0,sizeof(dp));
        dp[ 0 ][ 0 ]= 1 ;
         for ( int sta= 1 ;sta<( 1 <<n);sta++) // traverse all states 
        {
             int cnt= 0 ; // cnt indicates that the cnt topic has been arranged 
            for ( int i= 1 ;i<=n;i++) if (sta&( 1 <<(i- 1 ))) cnt++ ;

            for(int i=1;i<=n;i++)
            {
                if( ( sta & (1<<(i-1)) ) == 0 ) continue;

                for(int k=0;k<=m;k++)
                {
                    if(k+p[cnt][i]>=m) dp[sta][m]+=dp[sta^(1<<(i-1))][k];
                    else dp[sta][k+p[cnt][i]]+=dp[sta^(1<<(i-1))][k];
                }
            }
        }

        if(dp[(1<<n)-1][m]==0)
        {
            printf("No solution\n");
            continue;
        }

        int down=dp[(1<<n)-1][m];
        int up=fact[n];
        int g=gcd(up,down);
        printf("%d/%d\n",up/g,down/g);
    }
}

The time complexity is O(n 2 )+O(2 n mn)+O(lg(n!)). Obviously, when the data is large, the main impact item is O(2 n mn). According to the data size (2^12 )*12*500 ≈ 2e7, which is enough.

PS. Since the last time I did the topic of DP, I haven't done the topic of DP for a long time. I found that my understanding of DP is still not deep enough, and I forget it very quickly. It needs to be reviewed and consolidated.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324688626&siteId=291194637
Recommended