动态规划练习3

news/2025/2/25 23:45:16

题目描述:

      lw很喜欢玩一种战略游戏,在一个地图上,有n座城堡,每座城堡都有一定的宝物,在每次游戏中lw允许攻克m个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮lw算出要获得尽量多的宝物应该攻克哪M个城堡吗?

输入格式:

      第一行两个数,分别为n和m。接下来n行,每行两个数,第一个数a为攻克这个城堡前必须攻克的城堡,若a为0则该城堡可以直接攻克,第二个数b表示财宝数。

输出格式:

      第一行一个数,即最大财宝数。

样例输入:game.in

3 2

0 1

0 2

0 3

样例输出:game.out

5

数据范围:

对于30%的数据,n,m<=100。

对于100%的数据,n,m<=200。

题解:

首先,限制条件是选择m个物品,而每个物品最多选一次,跟0-1背包的区别在于有依赖关系,那么这层依赖关系我们可以借助于一个树来解决。借助dfs,从根节点开始dfs,然后直到叶子节点,回朔的时候进行0-1背包dp。

定义状态dp[i][j]表示在节点i,从以i为根节点的子树下选择j个城市的最大价值

初始化:dp[i][j]=val[i](i节点的价值)(1 < = j < = m)

转移方程 dp[father][j] = max (dp[father][j] dp[father][k]+dp[child][j-k]);由前面的dfs可见,我们是用子节点更新父节点,用j枚举父节点选择的城市数,k枚举留给其他子节点选择城市数,那么就可以转移了

注意:此题出给很多初始节点,也就是有很多森林,我们要设置一个超级root连接子树的根节点即可。

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<cstring>
using namespace std;
int f[1001][1001],n,m,a[1001];
int gi()
{
    int ans=0,f=1;
    char i=getchar();
    while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
    while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
    return ans*f;
}
struct node
{
    int to,next;
}edge[10001];
int head[1001],size;
void putin(int from,int to)
{
    size++;
    edge[size].to=to;
    edge[size].next=head[from];
    head[from]=size;
}
void dfs(int r)
{
    for(int i=head[r];i!=-1;i=edge[i].next)
    {
        dfs(edge[i].to);
        for(int j=m;j>=1;j--)
            for(int k=0;k<=j;k++)
            f[r][j]=max(f[r][j],f[r][k]+f[edge[i].to][j-k]);
    }
    for(int i=m+1;i>=1;i--)f[r][i]=f[r][i-1]+a[r];
}
int main()
{
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
    int i,j;
    memset(head,-1,sizeof(head));
    n=gi();m=gi();
    for(i=1;i<=n;i++)
    {
        int c=gi(),b=gi();
        a[i]=b;
        putin(c,i);
    }
    dfs(0);
    printf("%d",f[0][m+1]);
    return 0;
}

 

转载于:https://www.cnblogs.com/huangdalaofighting/p/7233857.html


http://www.niftyadmin.cn/n/4054433.html

相关文章

Java8流式编程GroupBy和求最值示例

流的创建(演示常用的) 数组创建 Arrays.stream Arrays的静态方法stream() 可以获取数组流 String[] arr { "a", "b", "c", "d", "e", "f", "g" };Stream<String> stream Stream.of(arr);Stre…

JavaScript中常见的字符串操作函数及用法汇总

转载地址&#xff1a;http://www.jb51.net/article/65358.htm这篇文章主要介绍了JavaScript中常见的字符串操作函数及用法,实例汇总了javascript常见的字符串转换、分割、查询、替换等技巧,非常具有实用价值,需要的朋友可以参考下。本文实例总结了JavaScript中常见的字符串操作…

基于Redis实现分布式定时任务调度

项目开发过程中&#xff0c;难免会有许多定时任务的需求进来。如果项目中还没有引入quarzt框架的情况下&#xff0c;我们通常会使用Spring的Schedule(cron"* * * * *")注解 样例如下&#xff1a; package com.slowcity.redis;import org.slf4j.Logger; import org.…

linux路由route

一、永久添加路由 重启network服务生效 支持用#注释 方法一 a、添加默认网关&#xff0c;即默认路由 两块网卡在配置文件ifcfg-ethX中不配置网关&#xff0c;在/etc/sysconfig/network中设置默认网关 vim /etc/sysconfig/network GATEWAY192.168.14.254 b、添加路由 创…

mybatis-plus开启sql日志打印

方法一&#xff1a; mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志或者&#xff1a;mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl #关闭sql日志 方法二&#xff1a; loggin…

phonegap(cordova) 自己定义插件代码篇(三)----支付宝支付工具整合

建议读者&#xff0c;先阅读官方文档&#xff0c;知晓其支付流程之后再来使用此代码&#xff0c;比方客户须要做什么&#xff0c;服务端须要做什么&#xff08;非常重要&#xff01;非常重要&#xff01;非常重要&#xff01;&#xff09;&#xff0c;由于这几个篇幅都是纯代码…

mybatis实现自定义分页插件

一、环境搭建 创建一个maven工程&#xff0c;然后引入mybatis依赖和mysql依赖即可。 <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.0.4</version> </dependency> <dependency…

Objective-C 引用计数原理

http://www.cocoachina.com/ios/20160112/14933.html 引用计数如何存储 有些对象如果支持使用 TaggedPointer&#xff0c;苹果会直接将其指针值作为引用计数返回&#xff1b;如果当前设备是 64 位环境并且使用 Objective-C 2.0&#xff0c;那么“一些”对象会使用其 isa 指针的…