• P2258 子矩阵——搜索+dp


    P2258 子矩阵

    二进制枚举套二进制枚举能过多一半的点;

    我们只需要优化一下第二个二进制枚举的部分;

    首先我们先枚举选哪几行,再预处理我们需要的差值,上下,左右;

    sum_shang,sum_heng

    然后DP查找最小值

    dp[i][j]表示前i列已经选了j列;

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=20;
    int n,m,r,c;
    int a[maxn][maxn];
    int id[maxn];
    int b[maxn];
    int sum_s[maxn];
    int sum_h[maxn][maxn];
    
    void pre_pare()
    {
        memset(sum_s,0,sizeof(sum_s));
        int num=0;
        for(int i=1;i<=n;i++) if(b[i]) id[++num]=i;
        for(int i=1;i<r;i++)
        {
            for(int j=1;j<=m;j++)
            {
                sum_s[j]+=abs(a[id[i]][j]-a[id[i+1]][j]);
            }
        }
        
        for(int i=1;i<=m;i++)
        {
            for(int j=i+1;j<=m;j++)
            {
                sum_h[i][j]=0;
                for(int k=1;k<=r;k++)
                {
                    sum_h[i][j]+=abs(a[id[k]][i]-a[id[k]][j]);
                }
            }
        }
        
    }
    
    int ans=2147483647,res=2147483647;
    int dp[maxn][maxn];
    
    int query()
    {
        memset(dp,0x3f,sizeof(dp));
        res=2147483647;
        for(int i=1;i<=m;i++)
        {
            dp[i][1]=sum_s[i];
            for(int j=2;j<=c;j++)
            {
                for(int k=1;k<i;k++)
                {
                    dp[i][j]=min(dp[i][j],dp[k][j-1]+sum_s[i]+sum_h[k][i]);
                }
            }
            res=min(res,dp[i][c]);
        }
        return res;
    }
    
    void dfs(int x,int sum)
    {
        if(sum>r) return ;
        if(x==n+1)
        {
            if(sum!=r) return ;
            pre_pare();
            ans=min(ans,query());
            return ;
        }
        b[x]=0;
        dfs(x+1,sum);
        b[x]=1;
        dfs(x+1,sum+1);
    }
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&r,&c);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        dfs(1,0);
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    排序算法合集(冒泡,选择,插入,堆排,快排)
    codeforces 632+ E. Thief in a Shop
    nyoj-一笔画问题-欧拉图+联通判定
    hdu-1179-二分图最大匹配
    hdu-2063-二分图最大匹配
    (转)二分图的最大匹配、完美匹配和匈牙利算法
    hdu-2444-二分图判定+最大分配
    C
    E
    C
  • 原文地址:https://www.cnblogs.com/WHFF521/p/11675228.html
Copyright © 2020-2023  润新知