낙곡 P1040 플러스 두 갈래 나무
https://www.luogu.org/problemnew/show/P1040
제목:
n n n 개의 노드가 있는 두 갈래 나무는 노드마다 하나의 점수가 있고 모든 자나무에도 점수가 있다. 각 자나무의 점수 계산 방법은 다음과 같다.× 오른쪽에 있는 나무의 가산점인 ubtr의 뿌리 점수.subtree의 왼쪽 나무의 가산점× subtreesubtree의 오른쪽 나무의 가산점인 subtreesubtree의 뿌리의 분수.subtree의 왼쪽 나무의 가산점×subtreesubtree의 오른쪽 나무의 가산점인 subtreesubtree의 뿌리의 분수.만약 어떤 하위 나무가 비어 있다면 그 가산점을 1로 규정하고 잎의 가산점은 잎 노드 자체의 분수이다.그것의 빈자 나무를 고려하지 않고 중서에 부합되는 두 갈래 나무 tr e tree tree (1,2,3,..., n) (1,2,3,..., n) (1,2,3,..., n) 를 시험적으로 구하십시오.출력 요구;(1)t r e tree tree의 최고 가산점 (2)t r e tree tree의 앞 순서 반복
생각:
우리는 dp[m][i][j]dp[m][i][j]dp[m][i][j]로 mm를 뿌리로 하고 자수는 i−ji-j의 나무의 최대 득점, sum[l]sum[l][r][r][r]로 자수 노드를 대표하는 i−ji-j의 자수의 최대 득점을 나타낸다. 그러면 dp[m][i]= max(dp[m]][i], (s u m [i][m−1]∗s u m [m + 1][j])∗a [m],su m [i] [j] = m a x (dp [m] [i] [j], su m [i] [j]) dp [m] [i] [j], (sum [i] [m-1] *sum [m+1] [j])* a[m],sum [i]=max (dp [m] [j],sum [i]) dp [m] [j], [i][m−1]∗sum[m+1][j]∗a[m]),sum[i][j]=max(dp[m][i][j],sum[i][j]),이렇게 상태 이동을 다 썼습니다. 뒤에 이 나무를 출력합니다. 구간의 최대치를 루트로 찾을 때마다그리고 왼쪽으로 오른쪽으로 돌아갑니다.
void First(int l, int r) {
int Max = 0, u = -1;
for (int i = l; i <= r; i ++) {
if(Max < dp[i][l][r]) {
Max = dp[i][l][r];
u = i;
}
}
if(l == 1 && r == n) printf("%lld
", Max);
printf("%d ", u);
if(u - 1 >= l) First(l, u-1);
if(u + 1 <= r) First(u+1, r);
}
AC 코드:
#include
using namespace std;
#define LL long long
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int Mod = 1e9 + 7;
const double eps = 1e-8;
typedef pair<int, int> psi;
void fre() {
if(freopen(" P1040.txt", "r", stdin) == NULL)
system("touch P1040.txt");
freopen(" P1040.txt", "r", stdin);
}
LL dp[40][40][40], a[40], sum[40][40];
int n;
void First(int l, int r) {
int Max = 0, u = -1;
for (int i = l; i <= r; i ++) {
if(Max < dp[i][l][r]) {
Max = dp[i][l][r];
u = i;
}
}
if(l == 1 && r == n) printf("%lld
", Max);
printf("%d ", u);
if(u - 1 >= l) First(l, u-1);
if(u + 1 <= r) First(u+1, r);
}
int main(int argc, char *args[]) {
fre();
scanf("%d", &n);
for (int i = 1; i <= n; i ++) scanf("%lld", &a[i]);
memset(dp, 0, sizeof(dp));
for (int i = 0; i <= n; i ++)
for (int j = 0; j <= n; j ++)
sum[i][j] = 1;
for (int i = 1; i <= n; i ++) dp[i][i][i] = sum[i][i] = a[i];
for (int k = 1; k <= n-1; k ++) {
for (int l = 1; l + k <= n; l ++) {
for (int m = l; m <= l + k; m ++) {
dp[m][l][l+k] = max(dp[m][l][l+k], (sum[l][m-1] * sum[m+1][l+k]) + a[m]);
sum[l][l+k] = max(sum[l][l+k], dp[m][l][l+k]);
}
}
}
First(1, n);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
낙곡 P1040 플러스 두 갈래 나무제목: n n n 개의 노드가 있는 두 갈래 나무는 노드마다 하나의 점수가 있고 모든 자나무에도 점수가 있다. 각 자나무의 점수 계산 방법은 다음과 같다.× 오른쪽에 있는 나무의 가산점인 ubtr의 뿌리 점수.sub...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.