• 拯救莫莉斯 状压dp


    题目大意:每个点有费用,要求选出花费最少的一些点,使得全部点都满足:他被选或与他相邻的任意点被选。

    没看清数据范围233333

    和翻格子游戏一样,考虑上中下三行,可行才能转移

    f[i][j][k]表示到第i行i-1行状态为j,i行状态为k,且i行以前的所有行均满足条件

    f[i][j][k]------>f[i+1][k][l]  j|k|l|(k<<1)|(k>>1) 覆盖所有棋子

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 55
    using namespace std;
    int a[N][N],cost[N][257],f[N][257][257],g[N][257][257],ans,tot,n,m;
    int bit[10];
    int getnum(int x){
        int nn=0;
        while(x){nn+=x&1;x>>=1;}
        return nn;
    }
    int main()
    {
        ans=0x7ffff; tot=0x7ffff;
        memset(f,0x3f,sizeof f);
        memset(g,0x3f,sizeof g);
        bit[0]=1; for(int i=1;i<=8;i++)bit[i]=bit[i-1]<<1;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++)
                scanf("%d",&a[i][j]);
            for(int j=0;j<(1<<m);j++)
                for(int k=1;k<=m;k++)
                    if(j&bit[k-1]) cost[i][j]+=a[i][k];
        }
        for(int i=0;i<(1<<m);i++){
            f[1][0][i]=cost[1][i];
            g[1][0][i]=getnum(i);
        }
        for(int i=2;i<=n;i++)
        {
            for(int j=0;j<(1<<m);j++)
                for(int k=0;k<(1<<m);k++)
                    for(int l=0;l<(1<<m);l++){
                        if((((j)|(k)|(l)|(k<<1)|(k>>1))&(bit[m]-1))<(bit[m]-1))continue;
                        if((f[i-1][j][k]+cost[i][l]<f[i][k][l])||((f[i-1][j][k]+cost[i][l]==f[i][k][l])&&(g[i-1][j][k]+getnum(l)<g[i][k][l]))){
                            f[i][k][l]=f[i-1][j][k]+cost[i][l];
                            g[i][k][l]=g[i-1][j][k]+getnum(l);
                        }
                    }
            if(i==n){
                for(int j=0;j<(1<<m);j++)
                    for(int k=0;k<(1<<m);k++){
                        if((((j)|(k)|(k<<1)|(k>>1))&(bit[m]-1))<(bit[m]-1))continue;
                        if(f[i][j][k]<ans||(f[i][j][k]==ans&&g[i][j][k]<tot)){
                            ans=f[i][j][k];
                            tot=g[i][j][k];
                        }
                    }
            }
        }
        printf("%d %d
    ",tot,ans);
        return 0;
    }


  • 相关阅读:
    SpringCloud教程第10篇:高可用的服务注册中心(F版本)
    SpringCloud教程第9篇:Sleuth(F版本)
    requests.session保持会话
    Jmeter Constant Throughput Timer 使用
    Jmeter提取响应数据的结果保存到本地的一个文件
    练习2
    练习1
    一道简单的练习题
    Maven下org.junit.Test无法使用
    [转]解决pycharm无法导入本地包的问题(Unresolved reference 'tutorial')
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/7746716.html
Copyright © 2020-2023  润新知