E - Maximum Sum Gym - 101853E

题目思路

作为dp白痴 这道简单状压dp都做了快一个半小时
dp太难了
这题反正一开始听lkw和zw讨论说是状压dp 因为他的n很小
晚上我找了下之前做的状压dp题的代码
还是写了很久才成功输出样例
然后一直在t 想了好久怎么优化
最后发现是初始化用memset才t的
有点头疼 不过吃一堑长一智把
改了之后都只有186ms了
这题还有一个挺坑的一点
就是他不止上下左右不能选 左上左下右上右下也不能选
加几个判断的函数就好了

ac代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 1<<16+5;
const int inf = 0x3f3f3f3f;
const ll llinf =0x3f3f3f3f3f3f3f3f;
const ll mod = 1000000007;
//998244353

int a[22][22];
int dp[20][maxn],ss[20][maxn];
int st[maxn];
vector<int>vec[maxn];
bool check(int x)
{
    return (x&(x<<1));
}

bool judge1(int x,int y)
{
    return (st[x]&st[y]);
}
bool judge2(int x,int y)
{
    return ((st[x])&(st[y]<<1));
}
bool judge3(int x,int y)
{
    return ((st[x])&(st[y]>>1));
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        for(int i=0;i<(1<<(n));i++)
        {
            if(!check(i))
            {
                st[k++]=i;
                //printf("%d\n",i);
            }
        }
        //printf("%d\n",k);
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<k;j++)
            {
                for(int s=1;s<=n;s++)
                {
                    if((1<<(s-1))&st[j])
                    {
                        ss[i][j]+=a[i][s];
                    }
                }
            }
        }
        for(int j=0;j<k;j++)
        {
            for(int s=0;s<k;s++)
            {
                if(!judge1(j,s)&&!judge2(j,s)&&!judge3(j,s))
                {
                    vec[j].push_back(s);
                    vec[s].push_back(j);
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<k;j++)
            {
                for(int u=0;u<vec[j].size();u++)
                {
                    int tem=vec[j][u];
                    dp[i][j]=max(dp[i][j],dp[i-1][tem]+ss[i][j]);
                }

            }
        }
        int maxx=0;
        for(int i=0;i<k;i++)
        {
            maxx=max(maxx,dp[n][i]);
        }
        printf("%d\n",maxx);
        for(int j=0;j<k;j++) vec[j].clear();
        for(int i=1;i<=n;i++)
            for(int j=0;j<k;j++)
                dp[i][j]=ss[i][j]=0;
    }
}

猜你喜欢

转载自blog.csdn.net/daydreamer23333/article/details/107736505