专栏文章
题解:P2258 [NOIP2014 普及组] 子矩阵
P2258题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miql0rtb
- 此快照首次捕获于
- 2025/12/04 06:32 3 个月前
- 此快照最后确认于
- 2025/12/04 06:32 3 个月前
题目地址
题目使用 dp做法最佳
因为还要枚举从哪里转移过来
而对于 的这种转移
一般还可以用单调队列优化dp使复杂度降一维
CPP#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
const int N=20;
int min=2147482647;
int map[N][N];
int qu[N];
int n,m,r,c;
int xx[N],yy[N][N];
int f[N][N];
void dp()
{
memset(xx,0,sizeof(xx));
memset(yy,0,sizeof(yy));
memset(f,127,sizeof(f));
for(int i=1;i<=m;i++)
for(int j=2;j<=r;j++)
xx[i]+=abs(map[qu[j]][i]-map[qu[j-1]][i]);
for(int i=1;i<=m;i++)
for(int j=i+1;j<=m;j++)
for(int k=1;k<=r;k++)
yy[i][j]+=abs( map[qu[k]][i]-map[qu[k]][j]);
for(int i=1;i<=m;i++) f[i][0]=0,f[i][1]=xx[i];
for(int i=1;i<=m;i++)
for(int j=2;j<=c;j++)
{
for(int k=1;k<i;k++)
f[i][j]=std::min(f[i][j],f[k][j-1]+yy[k][i]+xx[i]);
}
for(int i=1;i<=m;i++)
min=std::min(min,f[i][c]);
}
void dfs(int i,int step)
{
if(step==r+1)
{
dp();
return;
}
if(n-i<r-step) return;
for( ;i<=n;i++)
qu[step]=i,dfs(i+1,step+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",&map[i][j]);
dfs(1,1);
printf("%d\n",min);
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...