(KEI)1948 [データ]公式NOIP2014ユニバーサルセット部分行列(サブマトリックス。CPP / C / PAS)] [DFS + DP

(ファイルIO):入力:submatrix.in出力:submatrix.out
制限時間:1000msのスペースの制約:128000キロバイトの特定の制限


タイトルの説明は
、以下の定義が与えられる:
1.マトリックス:特定の行と(列のラインとは反対の順序を保持する)交点位置から行列の特定の列で構成新しいマトリックスを選択し、元の行列のサブ行列と呼ばれます。
例えば、以下左第二、および右側に2×3部分行列を与えるクロス位置に示した第2のエレメント列4、4、5を選択します。
ここに画像を挿入説明
2.隣接する要素:その上下の周りに四つの要素(もしあれば)との行列の要素が隣接しています。
3.スコアマトリックス:マトリックスとの隣接要素のそれぞれの差の絶対値。

表題タスク:n行m列を考えるとは正の整数行列は、この行列の部分行列の行r列Cを選択してくださいので、部分行列の最小値こと、および値を出力します。


入力
ファイル名を入力すると、submatrix.inです。
最初の行は、問題の重要性、二つの整数の間のスペースで区切られた各として、N、M、R、Cのスペースで区切られた4つの整数を含みます。
、各行がmを含むスペースで次のn行分離n行m列のマトリクスという問題を表す整数です。

出力
出力ファイルの名前submatrix.out。
記載の主題のサブ行列を満たす最小値を示す整数を含む全出力ライン、。


サンプル入力
サンプル入力1
。5 2. 3. 5
。9 3. 3. 3. 9
。9. 7. 8. 4. 4
。1. 4 6 7 6
6 8 9 5 6
7 4 5 6 1

入力2試料
7 7 3 3
7 7 7 6 2 10 5
5 8 8 2 1 6 2
2 9 5 6 1 7
7 9 3 6 1 7 8
1 9 1 4 7 8 8
11 8 10 10 5 9
1 3 1 5 4 8 6

サンプル出力
サンプル出力1
。6

サンプル出力2
16


範囲制限データ
【データ記述]
データの50%、1≤m≤12、1≤n ≤12、 マトリックス1≤[I、J]の各要素 ≤20、
データの100%、1≤ M≤16、1≤n≤16 、 マトリックス1≤[I、J]の各要素 ≤1000,1≤R <= N、1 <= C <= M。


ヒント
[O]サンプル記述1
行列の部分行列と行列の行4の元の行3列の最小値は、最初の列、第3列、第4列の要素位置の交差列5組成物、
ここに画像を挿入説明
その値は| 6から5 | + | 5 - 6 | + | 7から5 | + | 5から6 | + | 6から7 | + | 5から5 | + | 6から6 | = 6

サンプル2 [O]は説明
3行元の行列の4行目、5行目、6行2列、第6欄、列7 Crossの3列の行列の最小値のサブ行列を要素の位置は、サブマトリクスの選択された最小値
ここに画像を挿入説明


問題解決のためのアイデア
D F S + D P DFS + DP 突然、私は怠け者感じます。(実際には、コードを見て、それの一般的な考え方を理解することができるようになります)


コード
Yiyanbuge開口

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
int m,n,ans=2147483647,x,y,r,c,hh[100][100],f[100],a[100][100],bsy[100][100],b[100];
void dp(){
    memset(hh,0,sizeof(hh));
	memset(bsy,0,sizeof(bsy));
	memset(f,0,sizeof(f));
	b[r+1]=b[r];
	for(int i=1;i<=m;i++){
		for(int j=1;j<=r;j++)
			f[i]+=abs(a[b[j]][i]-a[b[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++)
			bsy[i][j]+=abs(a[b[k]][i]-a[b[k]][j]);
		}
	}
	for(int i=1;i<=m;i++)
		hh[1][i]=f[i];
	for(int i=2;i<=c;i++){
		for(int j=i;j<=m;j++){
			int t=2147483647;
			for(int k=i-1;k<j;k++){
				t=min(t,hh[i-1][k]+bsy[k][j]);
			}
			hh[i][j]=t+f[j];
		}
	}
	for(int i=c;i<=m;i++)
		ans=min(hh[c][i],ans);
}
void dfs(int x){
	if(y==r)
	{
		dp();
		return;
	}
	for(int i=x+1;i<=n;i++)
	{
		y++;
		b[y]=i;
		dfs(i);
		y--;
	}
}
int main()
{
    freopen("submatrix.in","r",stdin);
    freopen("submatrix.out","w",stdout);
    cin>>n>>m>>r>>c;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            cin>>a[i][j];
    dfs(0);
    printf("%d",ans);
}
公開された119元の記事 ウォンの賞賛8 ビュー4932

おすすめ

転載: blog.csdn.net/kejin2019/article/details/104618888
おすすめ