10.6西南联训爆0总结

T1 死亡颂唱者
问题描述

老王沉迷于lol不能自拔,召唤师峡谷是一个树状结构,总共有n个节点(3<=n<=1000),其中每条边的长度均为1,红方英雄全部在叶子节点处,每个叶子节点处都有一个红方英雄。可惜的是蓝方英雄死亡颂唱者经济太过领先,一个大招可以秒掉红方英雄。死亡颂唱者的大招是,在颂唱k秒后(1<=k<=n),对所有敌方英雄造成魔法伤害。前面说了,死亡颂唱者发育的非常好,大招可以秒杀红方英雄。但是红方为了不损失人头,决定在峡谷中一些节点处建造一些温泉使得所有英雄都是安全的。已有的一个基地温泉s(1<=s<=n),死亡颂唱者颂唱k秒,即红方英雄在k秒内到达任意一个温泉即是安全的,英雄的移动速度是1个单位每秒。

输入

第一个数t为数据的组数。对于每一组数据,前三个数分别为n,s,k。后面n-1行,每行2个数a,b。即a,b之间有一条边。

输出

对于每组数据,输出一行,即最少需要修建的温泉数。

样例输入输出

1
14
12 2
1 2
2 3
3 4
4 5
5 6
7 5
8 5
4 9
10 3
2 12
12 14
13 14
14 11


1

问题解决:问题无法解决,只能暴力,结果的确是暴力,什么LCA的的确是想多了。
要点:
(1)直接把s作为根先dfs一遍,更新可以保护以及不能保护的子节点。
(2)贪心原则:对于没能保护的节点,每次选择最深的子节点向上讨论k,直接在k放泉水,然后再以k更新cover数组。

#include<iostream>
#include<cstdio>
#include<vector> 
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn=1005;
vector<int> link[maxn],node[maxn];
int father[maxn];
bool cover[maxn];
int n,s,k;
void clear(){
    int i,j;
    for(i=0;i<=maxn;i++){
        link[i].clear();
        node[i].clear();
        memset(father,0,sizeof(father));
        memset(cover,0,sizeof(cover));
        //清空函数,为下一组数据做准备 
    }
}
void dfs(int u,int fa,int depth){
    father[u]=fa;
    if(link[u].size()==1&&depth>k)node[depth].push_back(u);
    //标记K范围以外的子节点 
    //link[u].size()==1,表示只连了一条边,即为子节点。 
    int i,j;
    for(i=0;i<link[u].size();i++){
        if(link[u][i]!=fa)dfs(link[u][i],u,depth+1);
    }
}
void dfs2(int u,int fa,int depth){
    cover[u]=true;
    if(depth==k)return;
    int i,j;
    for(i=0;i<link[u].size();i++){
        int v=link[u][i];
        if(v!=fa)dfs2(v,u,depth+1);
    }
    //更新保护标记 
}
int work(){//讨论未被覆盖的叶子节点 
    int i,j,d,tot=0;
    for(d=n-1;d>k;d--){//从最深处开始 
        for(i=0;i<node[d].size();i++){
            int u=node[d][i];
            if(cover[u])continue;//该节点已经被保护 
            int fa=u;
            for(j=1;j<=k;j++)fa=father[fa];
            dfs2(fa,-1,0);
            //贪心原则,直接强行钦点温泉 
            tot++;
        }
    }
    return tot;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        clear();
        scanf("%d%d%d",&n,&s,&k);
        int i,j;
        for(i=1;i<n;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            link[a].push_back(b);
            link[b].push_back(a);
        }
        dfs(s,-1,0);
        printf("%d\n",work());
    }
}

T2 上课不睡觉竟然会死

问题描述

子曰:不睡觉就会死。
深信此话的LYM决定在本学期接下来的n节课上考虑一下睡觉的问题。LYM认为如果在一堂课上睡觉,身体的疲劳值就会下降,反之如果在一堂课上不睡觉,身体的疲劳值就会上升。而身体对疲劳的忍耐是有限度的,一旦疲劳值超过限度,LYM就会go die,于是他不得不在一些课上睡觉。注意,LYM的疲劳值只会在一节课上完后发生改变,如果上完最后一节课后,疲劳值超出了限度,LYM仍然会go die。
不过,在不同的课上,疲劳值的变化量并不总是一样,就如在班主任的课上睡觉,疲劳值并不会下降太多,因为那样会睡得很不安心。
LYM是一个死要面子的人,他宁可冒着生命危险,也要挽回自己在老师心中的形象,因此他不能总是在人家的课上睡觉。他给自己定下了一个规矩:决不连续地在同一主科的课上睡觉,即如果LYM在主科X的某堂课上睡了觉,那么在下一堂(不一定是相邻的)主科
经过了这n节课后,LYM竟然没有死,LYM想知道自己对疲劳值的忍耐极限至少是多少。

输入格式


第一行,一个正整数n.

第二行,n个正整数,表示这n节课的课程安排。每个整数代表一门课程,科目代号对应关系参见下文的表格。(1~6号学科均为主科,7号学科不算作主科).

第三行,n个正整数,其中第i个数表示在第i节课上睡觉,疲劳值的减少量。

第四行,n个正整数,其中第i个数表示在第i节课上不睡觉,疲劳值的增加量。

第五行,一个整数,表示LYM的初始疲劳值。如果初始疲劳值大于了忍耐限度,LYM会在第一节课前就暴亡。

1-6号为主科,7号为其他


输出

一个整数,表示LYM的忍耐限度的最小可能值

样例输入输出

5
7 4 4 5 4
1 6 6 4 4
6 3 8 7 7
8


9

乍一看状态亚索+DP,于是把方程先列出来:

f[i][s] 表示已经上到第i节课,目前睡觉状态为s,最小的忍耐值。
对于其他,管都不管,直接睡——f[i][s]=f[i-1][s]-down[i];
对于主课:
如果睡:
则s&(1<<(a[i]-1))要为true,得到f[i][s]=f[i-1][s^(1<<(a[i]-1))]-down[i];
如果不睡:
对于本来就不能睡的:f[i][s]=min(f[i][s],f[i-1][s^(1<<(a[i]-1))]+up[i]);
对于可以睡但不睡的:f[i][s]=f[i-1][s]+up[i];

但是,状态转移时还应该被疲劳限度所限制,否则中途就可能GO DIE;
在不知道限度的情况下,要进行二分讨论。

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxs=63;
const int maxn=5050;
const int inf=2000000007;
int up[maxn],down[maxn],a[maxn];
int f[maxn][maxn];
int i,n,j,begin0,lasS;
bool ok(int x) {
    for(i=0; i<=maxs; i++)f[0][i]=inf;
    f[0][0]=begin0;
    for(i=1; i<=n; i++) {
        if(a[i]==7)
            for(lasS=0; lasS<=maxs; lasS++) {
                f[i][lasS]=inf;
                if(f[i-1][lasS]>x)continue;
                f[i][lasS]=f[i-1][lasS]-down[i];
            }
        else {
            for(lasS=0; lasS<=maxs; lasS++) {
                f[i][lasS]=inf;
                if(lasS&(1<<(a[i]-1))) {
                    if(f[i-1][lasS^(1<<(a[i]-1))]>x)continue;
                    f[i][lasS]=f[i-1][lasS^(1<<(a[i]-1))]-down[i];
                } else {
                    if(f[i-1][lasS]<=x) {
                        f[i][lasS]=f[i-1][lasS]+up[i];
                    }
                    if(f[i-1][lasS^(1<<(a[i]-1))]<=x) {
                        f[i][lasS]=min(f[i][lasS],f[i-1][lasS^(1<<(a[i]-1))]+up[i]);
                    }
                }
            }
        }
    }
    for(lasS=0; lasS<=maxs; lasS++) {
        if(f[n][lasS]<=x)return true;
    }
    return false;
}
int find() {
    int L=begin0,R=inf,mid;
    while(L<=R) {
        mid=(L+R)>>1;
        if(ok(mid))R=mid-1;
        else L=mid+1;
    }
    return L;
}
int main() {
    cin>>n;
    for(i=1; i<=n; i++)cin>>a[i];
    for(i=1; i<=n; i++)cin>>down[i];
    for(i=1; i<=n; i++)cin>>up[i];
    cin>>begin0;
    cout<<find();
    return 0;
}

T3 还没做。。。。。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ArcGIS 10.6 是一款地理信息系统 (GIS) 软件,用于分析、管理和可视化地理数据。然而,如果在特定情况下,ArcGIS 10.6 的可用性为0,可能是由以下原因导致: 1. 许可证问题:ArcGIS 10.6 需要有效的许可证才能正常运行。如果许可证已过期或无效,软件将无法使用。 2. 硬件要求不满足:ArcGIS 10.6 要求一定的硬件配置才能运行。如果您的计算机不满足最低要求,软件可能无法启动或运行不稳定。 3. 系统兼容性问题:ArcGIS 10.6 可能与您的操作系统或其他安装的软件不兼容。这可能导致软件无法加载或工作时崩溃。 4. 安装问题:如果软件没有正确安装,可能会导致其无法使用。在安装过程中出现错误或缺失关键文件可能会影响软件的可用性。 如果您在使用ArcGIS 10.6时遇到可用性为0的情况,您可以采取以下措施: 1. 检查许可证:确保您的许可证有效并已正确安装。如果许可证过期或无效,您可以联系ESRI或您的许可证提供商获取帮助和支持。 2. 检查硬件要求:确保您的计算机符合ArcGIS 10.6的最低硬件要求。如果不满足要求,您可能需要升级您的硬件或考虑使用更适合的软件版本。 3. 检查系统兼容性:确保您的操作系统和其他安装的软件与ArcGIS 10.6兼容。更新您的操作系统或与ArcGIS兼容的软件版本可能有助于解决兼容性问题。 4. 重新安装软件:如果软件没有正确安装,您可以尝试重新安装ArcGIS 10.6。确保按照ESRI提供的安装指南进行操作。 如果以上措施仍然无法解决问题,建议您联系ESRI技术支持或专业人士寻求帮助。只有他们才能提供更具体的解决方案,以确保ArcGIS 10.6的可用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值