zoukankan      html  css  js  c++  java
  • P2258 子矩阵

    子矩阵

    思路

    很容易想到这是一个动态规划,但是从题目来分析,不能很容易的设计出状态转移方程。

    原题为从矩阵中选出r行c列

    我们可以将问题进行化简,先对于原题进行dfs枚举行数

    对于每次枚举出来的r行m列,再进行一次动态规划

    对于在r行m列中选出c列来,其转移方程就非常容易得到了

    [f[i][j] = min_(f[k][j-1]+w[i]+v[k][i]) ]

    其中(w)数组是每列中元素的分值

    (v[i][j])则是第(i)与第(j)之间的分值

    (f[i][j])是选第(i)列作为第(j)行最小值

    (f)数组初始化为$$f[i][1]=w[i]$$

    总程序的时间复杂度主要由两部分构成

    dfs O((C_n^r))

    动态规划 O((m^3))

    总时间复杂度为O((C_n^rm^3))

    
    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    
    int a[23][233];
    int f[233][23];
    int v[233][233];
    int p[2333];
    int w[2333];
    int n,m;
    
    int r,c;
    int minn=1<<30;
    
    inline void dtgh()
    {
    	memset(f,0x7f,sizeof(f));
    	memset(w,0,sizeof(w));
    	memset(v,0,sizeof(v));
    	
    	
    	for(int i=1;i<=m;i++)   
    	{
    		for(int j=2;j<=r;j++)
    		w[i]+=abs(a[p[j-1]][i]-a[p[j]][i]);
    	}
    	
    	for(int i=1;i<=m;i++)
    		for(int j=i+1;j<=m;j++)
    		{
    			if(i == j) continue;
    			for(int t=1;t<=r;t++)
    			v[i][j]+=abs(a[p[t]][i]-a[p[t]][j]);
    		}
    
    	for(int i=1;i<=m;i++)
    	{
    		f[i][1]=w[i];
    	}
    	
    	for(int i=1;i<=m;i++)
    		for(int j=1;j<=min(c,i);j++)
    	{
    		for(int k=j-1;k<i;k++)
    		f[i][j]=min(f[i][j],f[k][j-1]+w[i]+v[k][i]);
    		
    		
    	} 
    	
    	for(int i=1;i<=m;i++)	
    	minn=min(minn,f[i][c]);
    }
    
    
    inline void dfs(int line,int step)
    {
    	
    	
    	
    	if(step == r+1)
    	{
    		dtgh();
    		return ;
    	}
    	
    	if(line > n) return;
    	
    	p[step]=line;
    	
    	dfs(line+1,step+1);
    	
    	dfs(line+1,step);
    
        
    }
    
    int main()
    {
    	
    	
    	ios_base::sync_with_stdio(false);
    	cout.tie(NULL);	
    	cin.tie(NULL);
    	
    	cin>>n>>m;
    	cin>>r>>c;
    	
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    	{
    		cin>>a[i][j];
    	}
    	
    	dfs(1,1);
    	
    	cout<<minn;
    } 
    
    

    end

  • 相关阅读:
    平均要取多少个(0,1)中的随机数才能让和超过1
    perl学习笔记
    K-means
    Mysql数据库常用操作整理
    ETL模型设计
    c++ 面试整理
    vim display line number
    inux 下的/etc/profile、/etc/bashrc、~/.bash_profile、~/.bashrc 文件的作用
    Linux命令大总结
    perl learning
  • 原文地址:https://www.cnblogs.com/-Iris-/p/13405581.html
Copyright © 2011-2022 走看看