标答做法,但WA了一个点,是什么原因,代码简明,希望指点一二
查看原帖
标答做法,但WA了一个点,是什么原因,代码简明,希望指点一二
421608
JMXZ楼主2023/7/24 07:40
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
int n,m,r,c;
int num[20][20];
int ch[20]={0},gs=1;//dfs数组
int lc[20],hc[20][20];
int f[20][20];//DP数组
void mems()//预处理
{
	memset(lc,0,sizeof(lc));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			hc[i][j]=0,f[i][j]=0x3f3f3f3f;
			
    for(int i=1;i<=m;i++)//预处理lc[i]
    {
       // lc[i]=0;
        for(int j=1;j<r;j++)
        {
            lc[i]+=abs(num[ch[j]][i]-num[ch[j+1]][i]);//计和
        }
    }
    for(int i=2;i<=m;i++)//预处理hc[i][j](前提条件:i>j)
    {
        for(int j=1;j<i;j++)
        {
            //hc[i][j]=0;
            for(int k=1;k<=r;k++)
            {
                hc[i][j]+=abs(num[ch[k]][i]-num[ch[k]][j]);//计和
            }
        }
    }
}
int minn=0x3f3f3f3f;
void dp()//DP
{
	int cmin;
    for(int i=1;i<=m;i++)//枚举i
    {
        cmin=min(i,c);//j的边界值(一定要注意不能大于c)
        for(int j=1;j<=cmin;j++)
        {
            if(j==1)//第一种边界
            {
                f[i][j]=lc[i];
            }
            else
            if(i==j)//第二种边界
            {
                f[i][j]=f[i-1][j-1]+lc[i]+hc[i][j-1];
            }
            else//正常情况
            {
                f[i][j]=2e8;//初始化,取inf
                for(int k=j-1;k<i;k++)//注意边界
                {
                    f[i][j]=min(f[i][j],f[k][j-1]+lc[i]+hc[i][k]);//取最小值
                }
            }
            if(j==c)minn=min(minn,f[i][c]);//存在此状态,则更新最小值
        }
    }
}
void dfs(int node)//枚举
{
    if(node>=r+1)//已经取到了一种状态
    {
        mems();
        dp();
        return;
    }
   for(int i=ch[node-1]+1;i<=n-r+node;i++)
   {
   		ch[node]=i;
   		dfs(node+1);
   		ch[node]=0;
   } 
}
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",&num[i][j]);
        }
    }
    dfs(1);//主要过程
    printf("%d",minn);//输出
    return 0;
}
2023/7/24 07:40
加载中...