POJ 1062 昂贵的聘礼(DP)

来源:互联网 发布:php 扩展开发 编辑:程序博客网 时间:2024/05/29 12:04

有区间限制的树形DP

开始以为等级限制为M时,只要等级和酋长的等级之差在小于等于M即可,实际上这是错的,因为可能有人的等级高于酋长,这些人和低于酋长的人的等级差可能大于M。

因此想到了枚举区间,然后在DP时只考虑在选定区间中的物品。

枚举区间的方法是先枚举区间长度,在枚举区间起点。


代码:

////  main.cpp//  1062 昂贵的聘礼////  Created by Baoli1100 on 15/4/7.//  Copyright (c) 2015年 Baoli1100. All rights reserved.//#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <cmath>using namespace std;#define INF 100000000int M,N;int d[105];vector<int> G[105];vector<int> P[105];int p[105];int l[105];int sl,tl;int dp(int n){    if(d[n]) return d[n];    d[n]=p[n];    for(int i=0;i<G[n].size();i++){        int cur=G[n][i];        if(l[cur]<=tl&&l[cur]>=sl){            int k=min(p[cur],dp(cur));            d[n]=min(d[n],k+P[n][i]);        }    }    return d[n];}int main(){    scanf("%d%d",&M,&N);    int bl=0,al=INF;    for(int i=1;i<=N;i++){        G[i].clear();        P[i].clear();        int n;        scanf("%d%d%d",&p[i],&l[i],&n);        bl=max(bl,l[i]);        al=min(al,l[i]);        for(int j=0;j<n;j++){            int t,k;            scanf("%d%d",&t,&k);            G[i].push_back(t);            P[i].push_back(k);        }    }    int res=INF;    for(int i=0;i<=M;i++){        for(int j=al;j<=bl-i;j++){            if(j>l[1]||j+i<l[1]) continue;            memset(d,0,sizeof(d));            sl=j;tl=j+i;            res=min(res,dp(1));        }    }    printf("%d\n",res);}


0 0
原创粉丝点击