Hdu 1011 Starship Troopers (DP 나무형 DP (배낭))
제목: 나무 한 그루 에 n 개의 정점 이 있 고 n - 1 개의 가장자리 가 있 습 니 다. 꼭대기 마다 bugs 가 있 습 니 다. 지금 폭탄 (폭탄 으로 하 세 요) 으로 폭격 해 야 합 니 다. 폭탄 하나 에 최대 20 마리 의 bug 가 폭사 합 니 다. 만약 에 어 딘 가 에 0 마리 의 bug 가 있다 면 다음 노드 로 굴 러 가서 폭격 할 수 있 습 니 다. n < = 100, 변 m < = 100
문제 풀이 방향: 비교적 간단 한 트 리 DP + 가방.본 문제 의 의존 관 계 는 나무 가장자리 로 이해 할 수 있다. 서브 노드 에 도착 하려 면 반드시 부모 노드 를 거 쳐 야 한다. 본질 은 똑 같다. 나 무 를 만 들 면 dp 를 어떻게 진행 하 는 지, 문제 풀이 의 핵심 은 서브 노드 에서 정 보 를 어떻게 얻 는 지 하 는 것 이다.
하나의 키 노드 는 m 개의 상 태 를 되 돌 릴 수 있 고 모든 상 태 는 용량 이 j 임 을 나타 낸다.(j < = m) 시 가장 많이 튀 긴 bug, 한 노드 중 한 상태 만 선택 하여 이동 할 수 있 습 니 다. 각 노드 에 몇 개의 키 노드 가 있 으 면 문 제 는 그룹 가방 으로 바 꿉 니 다. 몇 개의 하위 노드 는 몇 개의 그룹 가방 입 니 다. 부 피 는 몇 개의 장 소 를 선택 하고 가 치 는 Boos 의 가능성 입 니 다. 본 문 제 는 m 를 0 으로 특별히 판단 할 때 직접 출력 0 입 니 다.
상태 전이 방정식: dp [v] [1] = bug [v]; (v 는 잎 노드)
dp [v] [j] = max (dp [v] [j], dp [v] [j - i] + dp [k] [i]); (v 는 비 잎 노드 이 고 j 는 사용자 개 수 를 나타 내 며 i 는 용량 이 고 k 는 v 의 하위 노드 이다.) 알고리즘 복잡 도 O (sum (num [i], num [s]) (num [i] 는 특정한 노드 의 잎 자손 개수, num [s] 는 i 의 자식 노드 의 잎 자손 개수)
테스트 데이터:
5 10 50 10 40 10 40 20 65 30 70 30 1 2 1 3 2 4 2 5 1 1 20 7 5 0 50 10 40 10 40 20 65 30 70 30 1 2 1 3 2 4 2 5 4 1 0 10 0 10 0 10 0 10 1 2 2 3 1 4 -1 -1
코드:
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
#define MAX 110
#define max(a,b) (a)>(b)?(a):(b)
int val[MAX],need[MAX];
vector<int> tree[MAX];
int cnt,n,m,dp[MAX][MAX],vis[MAX];
void Tree_DP(int s){
if (vis[s]) return ;
vis[s] = 1;
int i,j,k,tp,temp;
for (i = need[s]; i <= m; ++i)
dp[s][i] = val[s];
for (i = 0; i < tree[s].size(); ++i) {
tp = tree[s][i];
if (vis[tp]) continue;
Tree_DP(tp);
for (j = m; j >= need[s]; --j)
for (k = 1; k + j <= m; ++k)
if (dp[tp][k]) {
temp = dp[s][j] + dp[tp][k];
dp[s][j+k] = max(dp[s][j+k],temp);
}
}
}
int main()
{
int i,j,k,a,b;
while (scanf("%d%d",&n,&m),n + m != -2){
for (i = 1; i <= n; ++i){
scanf("%d%d",&need[i],&val[i]);
tree[i].clear();
need[i] = (need[i] + 19) / 20;
}
for (i = 1; i < n; ++i){
scanf("%d%d",&a,&b);
if (a < b)
tree[a].push_back(b);
else
tree[b].push_back(a);
}
if (m == 0) {
printf("0
");
continue;
}
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
Tree_DP(1);
printf("%d
",dp[1][m]);
}
return 0;
}
이 글 은 ZeroClock 오리지널 이지 만 우 리 는 형제 이기 때문에 옮 길 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
물체 검출의 평가 지표 IoU의 계산 방법Yolo나 SSD 등 물체 검출에서 평가 지표로 사용되는 IoU에 대해 조사했으므로 정리했습니다. IoU (Intersection over Union)는 두 영역이 얼마나 겹치는지를 나타내는 지표입니다. 두 영역의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.