P1006 [Grupo de Melhorias NOIP2008] Passe a nota

descrição do tópico

Xiaoyuan e Xiaoxuan são bons amigos e colegas de classe e sempre têm assuntos intermináveis ​​para conversar juntos. Em uma atividade de desenvolvimento de qualidade, os alunos da turma se sentaram em um mmm linhannUma matriz com n colunas, e Xiaoyuan e Xiaoxuan estão dispostos em ambas as extremidades da diagonal da matriz, de modo que não podem se comunicar diretamente. Felizmente, eles podem se comunicar passando bilhetes. A nota será passada entre si por muitos colegas. Xiaoyuan fica no canto superior esquerdo da matriz e as coordenadas são(1,1) (1,1)( 1 ,1 ) , Xiaoxuan fica no canto inferior direito da matriz, coordenadas( m , n ) (m,n)( m ,n ) . A nota passada de Xiaoyuan para Xiaoxuan só pode ser passada para baixo ou para a direita, e a nota passada de Xiaoxuan para Xiaoyuan só pode ser passada para cima ou para a esquerda.

Durante a atividade, Xiaoyuan espera passar um bilhete para Xiaoxuan e, ao mesmo tempo, espera que Xiaoxuan responda a ele. Todos os alunos da classe podem repassar para eles, mas apenas uma vez, ou seja, se essa pessoa ajudar quando Xiaoyuan passar o bilhete para Xiaoxuan, então ele não ajudará quando Xiaoxuan passar para Xiaoyuan. Ajude novamente. vice-versa.

Há mais uma coisa para prestar atenção. A favorabilidade de cada aluno da classe é alta ou baixa (Nota: a bondade de Xiaoyuan e Xiaoxuan não está definida, use 0 0 ao entrar0 ), você pode usar[ 0 , 100 ] [0,100][ 0 ,100 ] para representar um número natural, quanto maior o número, melhor a intenção. Xiaoyuan e Xiaoxuan esperam encontrar alunos com altos níveis de bondade para ajudar a passar a nota o máximo possível, ou seja, encontrar dois caminhos de transmissão de ida e volta, para que a soma da gentileza dos alunos nesses dois caminhos seja o maior. Agora, por favor, ajude Xiaoyuan e Xiaoxuan a encontrar esses dois caminhos.

Formato de entrada

A primeira linha tem dois inteiros mm separados por espaçosm ennn , significa que hámmm linhannn colunas.

próximo mmm linhas são am × nm \times nm×A matriz de n , o iithna matrizeu remojjO número inteiro na coluna j significa estar noiieu remojjA bondade do aluno na coluna j . nnpara cada linhaOs n inteiros são separados por espaços.

Formato de saída

O arquivo de saída é composto por um inteiro por linha, que representa o valor máximo da soma das gentilezas dos alunos que participaram da passagem das notas nas duas idas e vindas.

Exemplo 1

Exemplo de Entrada #1

3 3
0 3 9
2 8 5
5 7 0

Saída de amostra nº 1

34

dica

【intervalo de dados】

Por 30% 30\%30% dos dados satisfazem1 ≤ m , n ≤ 10 1 \le m,n \le 101m ,n10 .
Para100% 100\%100% dos dados, satisfazendo1 ≤ m , n ≤ 50 1 \le m,n \le 501m ,n50

[fonte do tópico]

A terceira pergunta do grupo de aprimoramento do NOIP 2008.

linha de raciocínio

dp quadridimensional

Este problema é encontrar as duas maiores linhas que não se sobrepõem. Embora se diga que um começa no canto superior esquerdo e o outro no canto inferior direito, na verdade ambos começam no canto superior esquerdo, que é mais fácil de pensar e mais fácil de escrever
. , dp ! ! ! A melhor coisa a se pensar é o dp quadridimensional :
dp [ i ] [ j ] [ u ] [ v ] dp[i][j][u][v]d p ​​[ i ] [ j ] [ u ] [ v ] significa que a primeira linha atingiu( i , j ) (i, j)eu ,j ) , a segunda linha atinge( u , v ) (u,v)( você ,v )
Claro, duas linhas não podem ir para o mesmo ponto, então no loopi, j, u, vi,j,u,veu ,j ,você ,quando v ,vvv é começar dej + 1 j+1j+1 ,
ou julgar quando dois pontos coincidem,dp [i] [j] [u] [v] dp[i][j][u][v]d p ​​[ i ] [ j ] [ u ] [ v ] menos a bondade de uma pessoa

É melhor pensar na equação de transição de estado quadridimensional:

 f[i][j][k][l]=max( f[i][j-1][k-1][l] , max(f[i-1][j][k][l-1] , max(f[i][j-1][k][l-1] , f[i-1][j][k-1][l]) ) )+a[i][j]+a[k][l]

a é a bondade da entrada! ! !

Que tal isso? muito simples né?
No entanto, quando os dados são maiores, o quadridimensional não pode ser usado. Este 1 ≤ m , n ≤ 50 1≤m, n≤501m ,n50 é realmente um pouco aguado, então precisamos usar tridimensional,é claro que tridimensional também é fácil de entender.

dp tridimensional

Podemos descobrir que o número total de passos percorridos pelas duas rotas é o mesmo (ou seja, i + j i+jeu+j igual au + v u + vvocê+v ),portanto, podemos apenas enumerar as coordenadas verticais ou horizontais das duas linhas. (enumero as abcissas)

Então nosso atual dp [k] [i] [j] dp[k][i][j]d p ​​[ k ] [ i ] [ j ] significa queum total de k passos foram dados, a primeira linha está na i-ésima coluna e a segunda linha está na j-ésima coluna. Atenção
! ! ! A primeira dimensão da matriz dp deve ser aberta para n + m n+mn+Mais do que m , porque esta matriz de xadrez pode ir até cerca den + m n+mn+m etapas
Então nossa equação de transição de estado é:

dp[k][i][j]=max_(dp[k-1][i-1][j-1],dp[k-1][i][j],dp[k-1][i-1][j],dp[k-1][i][j-1])+a[i][k-i]+a[j][k-j];

max_ é uma função que encontra o valor máximo de quatro números, mas você também pode escrever três valores máximos
:
dp [ k − 1 ] [ i − 1 ] [ j − 1 ] dp[k-1][i-1 ][ j-1]d p ​​[ k1 ] [ eu1 ] [ j1 ] significa: ambas as linhas se movem para baixo na etapa anterior;
dp [ k − 1 ] [ i ] [ j ] dp[k-1][i][j]d p ​​[ k1 ] [ i ] [ j ] significa: ambas as linhas se movem para a direita no passo anterior;
dp [ k − 1 ] [ i − 1 ] [ j ] dp[k-1][i-1][j]d p ​​[ k1 ] [ eu1 ] [ j ] significa: no último degrau, um desce e o outro vai para a direita;
dp [ k − 1 ] [ i ] [ j − 1 ] dp[k-1][i][j-1]d p ​​[ k1 ] [ i ] [ j1 ] significa: no último degrau, um está à direita e o outro deve descer;
aaA matriz é a bondade da entrada

É isso, bem simples, não é? Dê uma olhada no código:

Contém notas, coma com confiança:

Código quadridimensional CA:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 55
using namespace std;
int a[N][N],f[N][N][N][N];
void work(int i,int j,int k,int l)
{
    
    
	int Max=0;
	Max=max(Max,f[i-1][j][k-1][l]);//这里可以合并,看个人喜好 
	Max=max(Max,f[i-1][j][k][l-1]);
	Max=max(Max,f[i][j-1][k-1][l]);
	Max=max(Max,f[i][j-1][k][l-1]);
	f[i][j][k][l]=Max+a[i][j];
	if(i!=k||j!=l)//去重,因为题目不允许走到同一个点 
	    f[i][j][k][l]+=a[k][l];
}
int main()
{
    
    
	int m,n,i,j,k,l;
	scanf("%d%d",&m,&n);
	for(i=1;i<=m;++i)
	    for(j=1;j<=n;++j)
	        scanf("%d",&a[i][j]);
	for(i=1;i<=m;++i)
	    for(j=1;j<=n;++j)
	        for(u=1;u<=m;++u)
	            for(v=1;v<=n;++v)
	                work(i,j,u,v);
	printf("%d",f[m][n][m][n]);
	return 0;
}

Código CA 3D:

#include<bits/stdc++.h>
using namespace std;
int n,m,a[101][101],dp[201][101][101];
int max_(int a,int b,int c,int d){
    
    
	return max(a,max(b,max(c,d)));//求最大的 
}
int main()
{
    
    
	cin>>n>>m;
	for(int i=1;i<=n;i++){
    
    
		for(int j=1;j<=m;j++){
    
    
			cin>>a[i][j];
		}
	}
	for(int k=2;k<=n+m;k++){
    
    //枚举步数 
		for(int i=1;i<=n;i++){
    
    //枚举横坐标 
			for(int j=1;j<=n;j++){
    
    //枚举横坐标 
				int l1=k-i,l2=k-j;
				if(l1<1||l1>m||l2<1||l2>m) continue;
				int t=a[i][l1];
				if(i!=j) t+=a[j][l2];//如果没有重复就加上 
				dp[k][i][j]=max_(dp[k-1][i-1][j-1],dp[k-1][i][j],dp[k-1][i-1][j],dp[k-1][i][j-1]);//求最大的 (函数) 
				dp[k][i][j]+=t;//加上当前位置的好心程度 
			}
		}
	}
	cout<<dp[n+m][n][n];//输出 
	return 0;
}

おすすめ

転載: blog.csdn.net/m0_61360607/article/details/132343221