D. 小srf的游戏(倒序思维+博弈+dp单调队列/线段树优化)

https://blog.csdn.net/zstuyyyyccccbbbb/article/details/112912657(先附上一个比较类似的题)


思路:观察样例,srf先手和qtc先手的答案就是取了个负号。所以就考虑srf先手的时候获得的得分-qtc得分的最大值。

为什么取负号呢?举个例子:

2 2

1 2

srf先手,必然是取2最优,这样qtc就没得取了。于是第一个答案为2

qtc先手,题目的意思实际上是想让你先考虑qtc-srf获得的最大得分 ,同样的,此时把qtc看成srf即可,取2是最优的。得分为2.最后题目说不管如果,输出srf-qtc的分,所以取负数。

因此到这里我们就单纯考虑srf先手的情况。

先正着想,srf取了i这个位置之后,qtc可以取i+1~i+m的一个数,但是正着扫过去的话会影响srf的后续状态。

到这里,这个题目就启发我们:如果正着状态是冲撞的,那么倒着来。而且极可能是一个类似dp的转移。

这里可以看一下昨天一场的烽火台题目,仿照设计。从后往前,dp[i]表示srf取了i这个数,此时[i~n]获得的srf先手-qtc得分的最大值。

考虑转移:dp[i]=a[i]-max(dp[i+1~i+m]);

这个转移各有各的方式,群友有的方程设计也不一样,转移也不同,然后我晕着迷糊了一晚上,早上按照自己的想法把这个题做了。如果不懂可以参考其他群友的博客。

(https://blog.csdn.net/weixin_45948940/article/details/112934074?utm_source=app&app_version=4.5.0

https://blog.csdn.net/tlyzxc/article/details/112976251

这个转移是这样的。srf取了i,由于博弈,也就是对手是个阿尔法狗,他会去找一个剩下的他能获得的最大值来使得这个答案尽可能小。在[i+1~i+m]中,狗是先手,他取一个最大的状态,也就是之前已经更新过的srf先手的一个状态,挑一个最大来使得得分变小。(博弈嘛)

最后这里是一个需要找最值的dp。我单调队列不是很熟悉,就上了线段树。单调队列的优化可以参考上面群聚的)

(注释处是朴素方程)

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
LL dp[maxn],a[maxn];
struct Tree{
    LL l,r,maxval,tag;///区间最大值
}tree[maxn*4];
void push_up(LL p)
{
    tree[p].maxval=max(tree[p*2].maxval,tree[p*2+1].maxval);
}
void addtag(LL p,LL d)
{
    tree[p].tag=d;
    tree[p].maxval=tree[p].tag;
}
void push_down(LL p)
{
    if(tree[p].tag!=-1){
        addtag(p*2,tree[p].tag);
        addtag(p*2+1,tree[p].tag);
        tree[p].tag=-1;
    }
}
void build(LL p,LL l,LL r)
{
    tree[p].l=l;tree[p].r=r;tree[p].maxval=0;
    tree[p].tag=-1;
    if(l==r) {tree[p].maxval=0;return;}
    LL mid=(l+r)>>1;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    push_up(p);
}
void modify(LL p,LL l,LL r,LL d)
{
    if(l<=tree[p].l&&r>=tree[p].r)///要修改的区间涵盖在区间内部
    {
            addtag(p,d);
            return;
    }
    push_down(p);
    LL mid=(tree[p].l+tree[p].r)>>1;
    if(l<=mid) modify(p*2,l,r,d);
    if(r>mid) modify(p*2+1,l,r,d);
    push_up(p);
}
LL query(LL p,LL l,LL r)
{
    if(l<=tree[p].l&&r>=tree[p].r)
    {
        return tree[p].maxval;
    }
    LL ans=-1e18;
    push_down(p);
    LL mid=(tree[p].l+tree[p].r)>>1;
    if(l<=mid) ans=max(ans,query(p*2,l,r));
    if(r>mid) ans=max(ans,query(p*2+1,l,r));
    return ans;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n,m;cin>>n>>m;
  build(1,1,n);
  for(LL i=1;i<=n;i++) cin>>a[i];
  for(LL i=1;i<=max(m,n)+10;i++) dp[i]=-1e18;
  dp[n]=a[n];  
  modify(1,n,n,a[n]);
  for(LL i=n-1;i>=1;i--){
    LL temp=-1e18;
    temp=max(temp,query(1,i+1,min(i+m,n)));
   // for(LL j=i+1;j<=min(i+m,n);j++){
   //     temp=max(dp[j],temp);
   // }
    dp[i]=a[i]-temp;
    modify(1,i,i,dp[i]);
  }
  LL ans=-0x3f3f3f3f;
  for(LL i=1;i<=m;i++){
    ans=max(ans,dp[i]);
  }
  cout<<ans<<endl<<-ans<<endl;
return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 在执行命令 "sudo gedit /etc/modprobe.d/blacklist.conf" 之前,你需要先卸载原有的N卡驱动。如果你是通过apt-get安装的原始驱动,可以使用以下命令卸载: "sudo apt-get remove --purge nvidia*"; 如果你是通过运行文件安装的原始驱动,可以使用以下命令卸载: "sudo chmod +x *.run" 和 "sudo ./NVIDIA-Linux-x86_64-384.59.run --uninstall"。在编辑blacklist.conf文件之前,你可能还需要修改GRUB配置文件,以确保nvidia驱动正确加载。你可以在GRUB配置文件中添加 "nvidia-drm.modeset=1" 或者 "nomodeset",具体的修改方式可能因电脑而异。你可以尝试编辑以下配置项: GRUB_DEFAULT=0 GRUB_TIMEOUT_STYLE=hidden GRUB_TIMEOUT=0 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nvidia-drm.modeset=1" GRUB_CMDLINE_LINUX=""。最后,你可以安装nvidia驱动,但在安装之前请确保你有足够的权限。你可以使用以下命令赋予权限: "sudo ./Linux-x86_64-396.18.run -no-x-check -no-nouveau-check -no-opengl-files"。这样安装后就不会出现循环登录的问题了。 #### 引用[.reference_title] - *1* [Ubuntu18.04英伟达驱动的安装](https://blog.csdn.net/srf_code/article/details/87260820)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Ubuntu18.04或20.04系统安装NVIDIA显卡驱动](https://blog.csdn.net/herocheney/article/details/123658573)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Ubuntu安装显卡驱动(避免循环启动问题)](https://blog.csdn.net/u013406197/article/details/103868234)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值