<gym101343J. Husam and the Broken Present 2> (状压DP)

The meaning of the question: Given n strings, the length of each string does not exceed 100 

   Find a new string such that all n strings are its strings. Output the minimum length of the new string

 

Problem solution: n is the complexity of the factorial of 15 n is definitely not good, so I thought of the complexity of 2 to the 15th power

   I thought of the state pressure, but I don't know how to maintain it, so it's good to add one dimension. dp[i][j] represents the current state bit i and the end is the jth string

       The transfer is simply mentally retarded. Preprocessing val[i][j] represents the length that the i-th string and the j-th string will be saved by splicing together. Then the answer is finally the total length minus the maximum saved length

   Then also pay attention to the problem of inclusion. If the three strings 3 4 of 1 2 3, 2 3 4 5 and 3 4 are included

   But when you transfer, 1 2 3 and 2 3 4 5 are connected together and become 1 2 3 4 5 including 3 4, but the state at this time still only uses the state of the first and second strings

   So just deduplicate the included strings... I wrote this for four hours for the mentally handicapped

 

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

int force 20 _
int num 20 _
int q[ 20 ][ 105 ]
int val[ 20 ][ 20 ]
int dp[ 70000 ][ 20 ];

intmain ()
{
    int n;
    scanf("%d", &n);

    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &q[i][0]);
        for(int j = 1; j <= q[i][0]; j++) scanf("%d", &q[i][j]);
    }
    for(int i = 1; i <= n; i++) vis[i] = 1;

    int cnt = 0;
    for(int i = 1; i <= n; i++)                //去重
    {
        if(!vis[i]) continue;
        for(int j = 1; j <= n; j++)
        {
            if(i == j) continue;
            if(!vis[j]) continue;

            if(q[i][0] >= q[j][0])
            {
                for(int k = 1; k + q[j][0] - 1 <= q[i][0]; k++)
                {
                    bool f = true;
                    for(int kk = 1; kk <= q[j][0]; kk++)
                    {
                        if(q[i][k + kk - 1] == q[j][kk]) continue;
                        else {f = false; break;}
                    }
                    if(f) {vis[j] = 0; break;}
                }
            }
        }
    }

    for(int i = 1; i <= n; i++) if(vis[i]) cnt++;

    int zn = 0;
    for(int i = 1; i <= n; i++) if(vis[i]) num[++zn] = i;

    for(int i = 1; i <= zn; i++)
    {
        for(int j = 0; j <= q[num[i]][0]; j++) q[i][j] = q[num[i]][j];
        ans += q[i][0];
    }

    for ( int i = 1 ; i <= cnt; i++)           // preprocess value 
    {
         for ( int j = 1 ; j <= cnt; j++ )
        {
            if(i == j) continue;
            val[i][j] = 0;
            for(int k = 1; k <= q[i][0]; k++)
            {
                if(q[i][k] == q[j][1])
                {
                    bool f  = true;
                    for(int kk = 1; kk + k <= q[i][0]; kk++)
                    {
                        if(q[i][k + kk] == q[j][kk + 1]) continue;
                        else { f = false; break;}
                    }
                    if(f) {val[i][j] = q[i][0] - k + 1; break;}
                }
            }
        }
    }
    memset(dp, 0, sizeof(dp));

    int sta = (1 << cnt) - 1;
    for(int i = 0; i <= sta; i++)
    {
        memset(vis, 0, sizeof(vis));
        for(int j = 0; j < n; j++)
        {
            int c = (i >> j) & 1;
            if(c == 1) vis[j + 1] = 1;
        }

        for(int j = 1; j <= n; j++)
        {
            if(vis[j]) continue;
            int v = (1 << (j - 1));

            for(int k = 1; k <= n; k++)
            {
                if(!vis[k]) continue;
                dp[i + v][j] = max(dp[i + v][j], dp[i][k] + val[k][j]);
            }
        }
    }

    int zd = 0;
    for(int i = 1; i <= cnt; i++) zd = max(zd, dp[sta][i]);
    printf("%d\n", ans - zd);
    return 0;
}

/*
3
3 1 2 3
2 3 4
4 2 3 4 5
*/
View Code

 

Guess you like

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