退役一年萌新求救
查看原帖
退役一年萌新求救
220342
梦语小猪头楼主2020/8/21 10:08

50分后面的点大部分都A了不知道哪里有错误呢。。 大概思路就是,先枚举行再选列,选列用DP处理 Fij表示以i结尾(且必须选i)已经选了j列

code:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
const int MAXN = 50;
long long Lcnt,B[MAXN][MAXN],A[MAXN][MAXN],W[MAXN],sum[MAXN][MAXN],F[MAXN][MAXN];
int n,m,r,c;
long long ans;
//bool vis[MAXN];
void dfs(int line)
{
	if(line == n + 1)return;
	Lcnt++;
	for(int i = 1;i <= m;i += 1)
		B[Lcnt][i] = A[line][i];
	if(Lcnt == r)
	{
		for(int i = 1;i <= m;i += 1)
		{
			W[i] = 0;
			for(int j = 2;j <= r;j += 1)
				W[i] += abs(B[j][i] - B[j - 1][i]);
		}
		for(int i = 1;i <= m;i += 1)
			for(int j = i + 1;j <= m;j += 1)
			{
				for(int k = 1;k <= n;k += 1)
					sum[i][j] += abs(B[k][i] - B[k][j]);
				sum[j][i] = sum[i][j];
			}
		for(int i = 1;i <= m;i += 1)
		{
			F[i][1] = W[i];
			for(int j = 2;j <= min(c,i);j += 1)
			{
				for(int k = j - 1;k < i;k += 1)
					F[i][j] = min(F[i][j],F[k][j - 1] + sum[i][k]);
				F[i][j] += W[i];
			}
		}
		for(int i = c;i <= m;i += 1)
			ans = min(ans,F[i][c]);
		memset(F,0x7f7f7f7f,sizeof(F));
		memset(sum,0,sizeof(sum));
	}
	else dfs(line + 1);
	Lcnt--;
	dfs(line + 1);
}
int main()
{
	cin >> n >> m >> r >> c;
	memset(F,0x7f7f7f7f,sizeof(F));
	for(int i = 1;i <= n;i += 1)
		for(int j = 1;j <= m;j += 1)
			cin >> A[i][j];
	ans = 1 << 10;
	dfs(1);
	cout << ans << endl;
	return 0;
}
2020/8/21 10:08
加载中...