hdu4340

本文探讨了一个两人合作攻占树状分布城市的最小总费用问题。通过动态规划算法,定义了节点的状态并进行了有效的状态转移,最终求出了最小总费用。

Capturing a country

Ant and Bob two army want to capture a country. The country is consist of N cities. To capture the city i, it takes Ant A[i] minutes, and Bob needs B[i] minutes to capture city i. Due to the similarity of neighboring cities, If the city i and j are neighboring cities, if Ant has captured city i, then the time for Ant to capture city j is A[j]/2. Of course if Ant has captured city j, then the time for Ant to capture city i is A[i]/2. It is the same for Bob. We define the total time to capture a country be the time to capture city 1 + the time to capture city 2 + … + the time to capture city N. Now we want to know the minimal total time.
For simplicity, we assume that there is only one path to go from one city to another city.

Input
The first line contains a integer N(0<\N<100), which is the number of cities.Then following N lines describe A[1], A[2], …, A[N];Then following N lines describe B[1], B[2], …, B[N];Next comes N-1 lines, each contains two integers x, y, meaning that city x and city y are neighboring.

Output
Just output the minimal total time in a single line.

Sample Input
3
1 2 5
3 8 1
1 2
1 3

Sample Output
3

题目描述:

有两个人要攻占树上的所有城市,每个人对于每一个城市都有相应的费用,但是如果一个人攻占的城市与他攻占的另外一个城市相连,那这个城市的费用就可以减半。问最后两个人攻占所有城市的总费用最小是多少。

每一个节点有四种状态:由哪一个人攻占,这个节点是否半价。比较麻烦的是如果只是指示当前节点是否半价的话,无法有效的进行状态转移。假如把颜色相同且相连的节点看做联通块的话那么每一个连通块都至少有一个全价的节点。
因此取dp[i][j][k] 表示第i个节点取j个颜色 (0 < j <2), k表示以当前节点为根的子树里面是否有颜色为j 的全价节点 (0 < k <2)。
k 等于0的时候比较简单,该节点的每一个子节点要么取相同颜色的半价,要么取另外一种颜色,并且该节点的子树里面一定有全价节点。
k等于1的时候就有两种情况了, 首先是自己本身取全价,另外一种是子树里面的某一个节点取全价。这个时候可以用一个变量表示某一个子树由全部半价变成有一个全价的差值。显然要取这个变化量的最小值。详见代码:
参考了:这里

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
typedef  long long LL;

#define clr(x) memset((x),0,sizeof(x))
#define inf 0x3f3f3f3f

using namespace std;
int a[110];
int b[110];
vector <int> v[110];
int dp[110][2][2];
int n;
void dfs(int x,int fa)
{
    int t1=0,t2=0;
    int c1=inf,c2=inf;  //变化量
    int flag = 0;
    for(int i = 0;i<v[x].size();i++) if(v[x][i]!=fa)
    {
        dfs(v[x][i],x);
        flag = 1;
        t1 += min(dp[v[x][i]][0][0],dp[v[x][i]][1][1]);
        t2 += min(dp[v[x][i]][1][0],dp[v[x][i]][0][1]);
        c1 = min(c1,dp[v[x][i]][0][1] - min(dp[v[x][i]][0][0],dp[v[x][i]][1][1]));
        c2 = min(c2,dp[v[x][i]][1][1] - min(dp[v[x][i]][1][0],dp[v[x][i]][0][1]));

    }
    if(!flag)
    {
        dp[x][0][0] = a[x]/2;
        dp[x][1][0] = b[x]/2;
        dp[x][0][1] = a[x];
        dp[x][1][1] = b[x];
    }
    else {
        dp[x][0][0] = a[x]/2+t1;
        dp[x][1][0] = b[x]/2+t2;
        dp[x][0][1] = min(a[x]+t1,a[x]/2+t1+c1);
        dp[x][1][1] = min(b[x]+t2,b[x]/2+t2+c2);
    }

}
int main()
{
   while(~scanf("%d",&n))
   {
       int x,y;
       for(int i = 1;i<=n;i++)
           scanf("%d",&a[i]);
       for(int i = 1;i<=n;i++)
           scanf("%d",&b[i]);
        for(int i = 1;i<=n;i++) v[i].clear();
       for(int i = 1;i<n;i++)
       {
           scanf("%d%d",&x,&y);
           v[x].push_back(y);
           v[y].push_back(x);
       }
       memset(dp,0,sizeof dp);
       dfs(1,-1);
       printf("%d\n",min(dp[1][1][1],dp[1][0][1]));
   }

    return 0;
}
标题基于SpringBoot的马术俱乐部管理系统设计与实现AI更换标题第1章引言介绍马术俱乐部管理系统的研究背景、意义、国内外研究现状、论文方法及创新点。1.1研究背景与意义阐述马术俱乐部管理系统对提升俱乐部管理效率的重要性。1.2国内外研究现状分析国内外马术俱乐部管理系统的发展现状及存在的问题。1.3研究方法以及创新点概述本文采用的研究方法,包括SpringBoot框架的应用,以及系统的创新点。第2章相关理论总结和评述与马术俱乐部管理系统相关的现有理论。2.1SpringBoot框架理论介绍SpringBoot框架的基本原理、特点及其在Web开发中的应用。2.2数据库设计理论阐述数据库设计的基本原则、方法以及在管理系统中的应用。2.3马术俱乐部管理理论概述马术俱乐部管理的基本理论,包括会员管理、课程安排等。第3章系统设计详细描述马术俱乐部管理系统的设计方案,包括架构设计、功能模块设计等。3.1系统架构设计给出系统的整体架构,包括前端、后端和数据库的交互方式。3.2功能模块设计详细介绍系统的各个功能模块,如会员管理、课程管理、预约管理等。3.3数据库设计阐述数据库的设计方案,包括表结构、字段设计以及数据关系。第4章系统实现介绍马术俱乐部管理系统的实现过程,包括开发环境、编码实现等。4.1开发环境搭建介绍系统开发所需的环境,包括操作系统、开发工具等。4.2编码实现详细介绍系统各个功能模块的编码实现过程。4.3系统测试与调试阐述系统的测试方法、测试用例以及调试过程。第5章系统应用与分析呈现马术俱乐部管理系统的应用效果,并进行性能分析。5.1系统应用情况介绍系统在马术俱乐部中的实际应用情况。5.2系统性能分析从响应时间、并发处理能力等方面对系统性能进行分析。5.3用户反馈与改进收集用户反馈,提出系统改进建议。第6章结论与展望总结马术俱乐部管理系统的设计与实现成果,并展望未来的研究
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值