洛谷 2258

    这道题我们一看数据范围第一感觉是状压DP,将每一列的选与不选看成是一个二进制数,但是这道题我们考虑如果知道了每一列选与不选,我们每一行的差值,现在问题就变成了在n列中选r行使其形成的矩阵值最小。我们可以考虑DP,F[i][j][k]表示在i这个状态,选了j行,最后一行选的是第k行,形成矩阵的最小值,转移模仿LIS的转移,我们可以预处理出合法的状态,然后再处理出在这个状态下任意两行相邻后的值,以及这个状态下每行的值,状态量最多是C(16,8),DP复杂度是O(n^3),勉强可以过掉。

#include
#include
#include
using namespace std;
int list[20000],tot;
int n,m,r,c,a[20][20],ans=1e9;
int g[20000][17][17],cha[20000][17],f[20000][17][17];
bool flag[17];

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]);
	int R=1<


你可能感兴趣的:(DP)