Number of squares taken HDU-1565- (1) (like pressure DP)

Access box (1)

Problem Description

Give you a grid of n * n board, each grid which has a non-negative number.
Lattice removed from two numbers where the number of a plurality of such arbitrary no common edge, that is taken where the number of two adjacent lattice can not, and is taken out and the maximum number.

Input

Comprising a plurality of test cases, each test case comprising an integer n and n * n non-negative (n <= 20)

Output

For each test case, output might get the biggest and

Sample Input

3
75 15 21 
75 15 28 
34 70 5 
 

Sample Output

188
 

Problem-solving ideas:

Give legal status to play tag, and then turn enumerate enumerate each state on it.
(Garbage topic ruined my youth, RE two hours, n can actually equal to 0)

AC Code:

#include <bits/stdc++.h>
#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include <cstring>
#include <utility>
#include <string>
#define INF 0xfffffff
#define int long long

using namespace std;
const int mod = 1e9+7;
const int N = 20;
int a[N][N];
int mark[1<<17];
int cnt_=0;
int dp[N][1<<17];

int get_sum(int lev,int sta,int n)
{
    int sum = 0;
    for(int i = 0; i < n ; i ++)
    {
        if(((1<<i)&sta) != 0)
            sum += a[lev][i];
    }
    return sum;
}

signed main()
{
    int n;
    for(int i = 0 ; i < (1<<17) ; i ++)
    {
        if((i&(i<<1)) == 0)
            mark[cnt_++] = i;
    }
    while(cin>>n)
    {
        if(n == 0){
                cout<<0<<endl;
            continue;
        }
        for(int i = 0 ; i < n ; i ++)
            for(int j = 0 ;  j < n ; j ++)
                cin>>a[i][j];
        memset(dp,0,sizeof(dp));
        for(int i = 0; mark[i] < (1<<n) ; i++)
            dp[0][mark[i]] = get_sum(0,mark[i],n);
        for(int i = 1; i < n ; i ++)
        {
            for(int j = 0 ;  mark[j] < (1<<n) ; j ++)
            {
                int val = get_sum(i,mark[j],n);
                for(int k = 0 ; mark[k] < (1<<n) ; k ++)
                {
                    if((mark[k]&mark[j]) == 0)
                        dp[i][mark[j]] = max(dp[i][mark[j]],dp[i-1][mark[k]]+val);
                }
            }
        }
        int ans  = 0;
        for(int j = 0 ;  mark[j] < (1<<n) ; j ++)
            ans = max(ans,dp[n-1][mark[j]]);
        cout<<ans<<endl;
    }
    return 0;
}

Published 104 original articles · won praise 7 · views 4067

Guess you like

Origin blog.csdn.net/qq_43461168/article/details/104144620