NOIP模拟(20171026)T3 大逃杀

本文介绍了一种基于树形结构的动态规划算法,用于解决在一棵带权树中,在限定时间内获取最大武力值的问题。文章详细展示了状态定义、状态转移方程及实现代码。

一棵带权树,第一次经过一个节点需ti时间,获得wi的武力值
求T时间内获得的最大武力值
n,T300
树形dp神题(告诉了我什么叫转移顺序)
dp[i][j][0/1/2]表示路径的 【起点终点都在i/起点(或终点)在i,另一点在i的子树内(因为路径是可逆的)/起点终点都在i的子树】 内能得到的最大武力值
转移即可(说的容易!!!)
dp[i][j][2]dp[i][jdis(i,v)2k][2]+dp[v][k][0](vson[i])
dp[i][j][2]dp[i][jdis(i,v)2k][0]+dp[v][k][2](vson[i])
dp[i][j][2]dp[i][jdis(i,v)k][1]+dp[v][k][1](vson[i])
dp[i][j][1]dp[i][jdis(i,v)2k][1]+dp[v][k][0](vson[i])
dp[i][j][1]dp[i][jdis(i,v)k][0]+dp[v][k][1](vson[i])
dp[i][j][0]dp[i][jdis(i,v)2k][0]+dp[v][k][0](vson[i])
注意,转移时一定一定一定要用上一个子树的状态来更新这个子树的状态(类似背包的降维优化)
注意,树边权可为0(个中含义自行体会)

#include<bits/stdc++.h>
#define LEN 350
/*中间一对地方不能反,反了的话,呵呵*/
using namespace std;
inline int getint(){
    int x=0,p=1;
    char c=getchar();
    while(!isdigit(c)){
        if(c=='-')p=-1;
        c=getchar();
    }
    while(isdigit(c)){
        x=(x<<3)+(x<<1)+(c^'0');
        c=getchar();
    }
    return x*p;
}
inline void putint(long long x){
    if(x<0){
        x=-x;
        putchar('-');
    }
    static int buf[30];
    int tot=0;
    do{
        buf[tot++]=x%10;
        x/=10;
    }while(x);
    while(tot)putchar(buf[--tot]+'0');
}
int n,T;
struct road{
    int e,nxt,len;
}r[LEN*2];
struct node{
    int first,fa,w,t;
    int dp[LEN][5];
}t[LEN];
int tot=1;
inline void creat(int a,int b,int c){
    r[++tot].e=b;
    r[tot].len=c;
    r[tot].nxt=t[a].first;
    t[a].first=tot;
}
int ans=0;
void dfs(int cur){
    for(int i=0;i<=300;++i){
        for(int j=0;j<5;++j){
            t[cur].dp[i][j]=-0xfffffff;
        }
    }
    for(int i=t[cur].t;i<=300;++i){
        t[cur].dp[i][0]=t[cur].dp[i][1]=t[cur].dp[i][2]=t[cur].w;
    }
    for(int i=t[cur].first;i;i=r[i].nxt){
        int v=r[i].e;
        if(v==t[cur].fa)continue;
        t[v].fa=cur;
        dfs(v);
        for(int j=T;j>=0;--j){                     //不能反
            for(int k=0;k<=T;++k){                 //不能反*2
                if(j-r[i].len*2-k>=t[cur].t) t[cur].dp[j][2]=
                max(t[cur].dp[j][2], t[cur].dp[j-r[i].len*2-k][2]+t[v].dp[k][0]);
                if(j-r[i].len*2-k>=t[cur].t) t[cur].dp[j][2]=
                max(t[cur].dp[j][2],t[cur].dp[j-r[i].len*2-k][0]+t[v].dp[k][2]);
                if(j-r[i].len-k>=t[cur].t) t[cur].dp[j][2]=
                max(t[cur].dp[j][2],t[cur].dp[j-r[i].len-k][1]+t[v].dp[k][1]);
                if(j-r[i].len*2-k>=t[cur].t) t[cur].dp[j][1]=
                max(t[cur].dp[j][1],t[cur].dp[j-r[i].len*2-k][1]+t[v].dp[k][0]);
                if(j-r[i].len-k>=t[cur].t) t[cur].dp[j][1]=
                max(t[cur].dp[j][1],t[cur].dp[j-r[i].len-k][0]+t[v].dp[k][1]);
                if(j-r[i].len*2-k>=t[cur].t) t[cur].dp[j][0]=
                max(t[cur].dp[j][0],t[cur].dp[j-r[i].len*2-k][0]+t[v].dp[k][0]);
                //不能反*3
            }
        }
    }
    //cout<<cur<<endl;
    for(int j=T;j>=0;--j){
        //cout<<j<<" "<<t[cur].dp[j][0]<<" "<<t[cur].dp[j][1]<<" "<<t[cur].dp[j][2]<<endl;
        ans=max(ans,max(t[cur].dp[j][0],(t[cur].dp[j][1],t[cur].dp[j][2])));
    }
}
int main(){
    n=getint(),T=getint();
    bool f=1;
    for(int i=1;i<=n;++i){
        t[i].w=getint();
        if(t[i].w)f=0;
    }
    if(f){
        cout<<0;
        return 0;
    }
    for(int i=1;i<=n;++i){
        t[i].t=getint();
    }
    for(int i=1;i<n;++i){
        int a=getint(),b=getint(),c=getint();
        creat(a,b,c),creat(b,a,c);
    }
    dfs(1);
    cout<<ans<<endl;
    return 0;
}
基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值