首页 > 其他分享 >大盗阿福(线性DP)

大盗阿福(线性DP)

时间:2024-10-30 23:46:11浏览次数:3  
标签:大盗 return int sum cin dfs 阿福 home DP

在这里插入图片描述

一、递归写法(dfs深搜)

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int>PII;

const int N = 507;
int home[N],mem[N];
int n;

int dfs(int x)
{
    if (x > n) return 0;    

    return max(dfs(x + 1), dfs(x + 2) + home[x]);   //不选/选
}

void solve()
{
    memset(home, 0, sizeof(home)); //因为有多组测试样例,所以每一轮都需要初始化操作
     cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> home[i];
    }
    int res=dfs(1);
    
    cout << res << '\n';
}


int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int _ =1; cin >> _;
    while (_--) solve();

    system("pause");
    return 0;
}

二、记忆化搜索

  • 对于已经计算过了的数据不做重复计算,如图中计算了两次店铺4的价值,造成了代码累赘,完全可以用一个记忆化数组mem来存储
  • 由于没有return函数直接返回,所以需要用条件判断把语句关联在一起,防止越界
#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int>PII;

const int N = 507;
int home[N],mem[N];
int n;

int dfs(int x)
{
    if (mem[x]) return mem[x];  //记忆化搜索数组

    int sum = 0;

    if (x > n) sum=0;    //注意:由于没有return函数直接返回,所以需要用条件判断把语句关联在一起,防止越界
    else  sum=max(dfs(x + 1), dfs(x + 2) + home[x]);   //不选/选
    
    mem[x] = sum;
    return sum;
}

void solve()
{
    memset(home, 0, sizeof(home)); //因为有多组测试样例,所以每一轮都需要初始化操作
     cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> home[i];
    }
    int res=dfs(1);
    
    cout << res << '\n';
}


int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int _ =1; cin >> _;
    while (_--) solve();

    system("pause");
    return 0;
}

三、动态规划(dp)–>倒序

PS:应该于dfs的公式一致

  • 由于到递归中,只有归的操作才是产生答案的操作,那么我们是否可以仅仅对归进行操作,从而得出答案呢?–>于是,dp产生了
  • 相当于我们从边界往回进行倒序遍历,从已知推未知,所以应该是for (int i = n; i >= 1; i--)
  • 注意:p[i]表示从n-i的最大店铺的值,所以应该输出dp[1]
#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int>PII;

const int N = 507;
int home[N],mem[N],dp[N];
int n;

int dfs(int x)
{
    if (mem[x]) return mem[x];  //记忆化搜索数组

    int sum = 0;

    if (x > n) sum=0;    //注意:由于没有return函数直接返回,所以需要用条件判断把语句关联在一起,防止越界
    else  sum=max(dfs(x + 1), dfs(x + 2) + home[x]);   //不选/选
    
    mem[x] = sum;
    return sum;
}

void solve()
{
    memset(home, 0, sizeof(home)); //因为有多组测试样例,所以每一轮都需要初始化操作
     cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> home[i];
    }
    for (int i = n; i >= 1; i--)
    {
        dp[i] = max(dp[i + 1], dp[i + 2] + home[i]);
    }
    cout << dp[1];  //表示从n-i的最大店铺的值,所以应该输出dp[1]
}


int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int _ =1; cin >> _;
    while (_--) solve();

    system("pause");
    return 0;
}

四、动态规划(正序)

在这里插入图片描述

  • 那么倒序看起来奇奇怪怪的,我们是否可以正序呢??答案是肯定的,此时我们的搜索方向与原来的恰恰相反,也就是从n开始搜索
  • 注意这道题还有一个映射的思想,同时扩大嘿嘿嘿
#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int>PII;

const int N = 507;
int home[N],mem[N],dp[N];
int n;

int dfs(int x)
{
    if (mem[x]) return mem[x];  //记忆化搜索数组

    int sum = 0;

    if (x > n) sum=0;    //注意:由于没有return函数直接返回,所以需要用条件判断把语句关联在一起,防止越界
    else  sum=max(dfs(x + 1), dfs(x + 2) + home[x]);   //不选/选
    
    mem[x] = sum;
    return sum;
}

void solve()
{
    memset(home, 0, sizeof(home)); //因为有多组测试样例,所以每一轮都需要初始化操作
     cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> home[i];
    }
    for (int i = 1; i<=n; i++)
    {
        //dp[i] = max(dp[i - 1], dp[i - 2] + home[i]);
        dp[i+2] = max(dp[i+1], dp[i] + home[i]);
    }
    cout << dp[n+2];  //表示从1-n的最大店铺的值,所以应该输出dp[n]
}


int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int _ =1; cin >> _;
    while (_--) solve();

    system("pause");
    return 0;
}
``

标签:大盗,return,int,sum,cin,dfs,阿福,home,DP
From: https://blog.csdn.net/2301_79365218/article/details/143377565

相关文章

  • dpdk环境搭建
    系统配置ubuntu22.04dpdk21.11修改grub配置sudovim/etc/default/grub这里是进行配置大页内存,在修改之前需要查看自己机器的配置,根据自己的机器配置进行修改等等GRUB_CMDLINE_LINUX="intel_iommu=oniommu=ptvfio_pci.enable_sriov=1vfio_pci.disable_idle_d3=1us......
  • 本地搭建AI证件照神器HivisionIDPhotos轻松自己在线制作证件照
    文章目录前言1.安装Docker2.本地部署HivisionIDPhotos3.简单使用介绍4.公网远程访问制作照片4.1内网穿透工具安装4.2创建远程连接公网地址5.配置固定公网地址前言本文主要介绍如何在Linux系统使用Docker快速部署一个AI证件照工具HivisionIDPhotos,并结合cpol......
  • 【重磅新品】芯驿电子 ALINX 推出全新 IP 核产品线,覆盖 TCP/UDP/NVMe AXI IP 核
    在创新加速的浪潮中,为更好地响应客户群需求,芯驿电子ALINX推出全新IP核产品线,致力于为高性能数据传输和复杂计算需求提供高带宽、低延迟的解决方案。发布的第一批IP核包括10GBe/40GBeUDP协议栈IP核、10GbETCP/IP协议栈IP核和NVMeAXIIP核。 ALINX发布的10Gb......
  • 2024年国际关系、外交学与政治学国际学术会议(ICIEDPS 2024)
    2024年国际关系、外交学与政治学国际学术会议(ICIEDPS2024)2024InternationalConferenceonInternationalRelations,DiplomacyandPoliticalScience(ICIEDPS2024)会议信息大会官网:2024年国际关系、外交学与政治学国际学术会议(ICIEDPS2024)投稿邮箱:[email protected]......
  • .NET中的线程池ThreadPool(链接)
    微软推荐在.NET中使用多线程开发时,都使用线程池,下面这篇微软文档介绍了.NET中的线程池类ThreadPool:ThreadPoolClass注意上面文档中的这句话:Thereisonethreadpoolperprocess.也就是说,每个.NET进程(process)中有一个线程池,线程池在每个.NET进程中只有一个,一个.NET进程中......
  • 一些dp题
    P3736[HAOI2016]字符合并有一个长度为\(n\)的\(01\)串,你可以每次将相邻的\(k\)个字符合并,得到一个新的字符并获得一定分数。得到的新字符和分数由这\(k\)个字符确定。你需要求出你能获得的最大分数。\(1≤n≤300\),\(1<k≤8\)。\(c_i∈{0,1}\),\(1≤w_i≤10^9\)。......
  • Atcoder DP Contest
    好像都在说这套题很好,所以来刷一遍太水的就只放代码了尚未完工,先发一下猫猫可爱捏https://www.tldraw.com/ro/1g8hQBpWTkduIlFxT3c0P?d=v-1275.1523.960.968.pageA.Frog1#include<bits/stdc++.h>usingnamespacestd;intn;inth[100001];intf[100001];intmain(){ ......
  • 01背包问题(经典dp题解)
    有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。第 ii 件物品的体积是 vi,价值是 wi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。输入格式第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。接下来......
  • 【linux网络编程】| socket套接字 | 实现UDP协议聊天室
        前言:本节内容将带友友们实现一个UDP协议的聊天室。主要原理是客户端发送数据给服务端。服务端将数据再转发给所有链接服务端的客户端。所以,我们主要就是要实现客户端以及服务端的逻辑代码。那么,接下来开始我们的学习吧。    ps:本节内容建议了解so......
  • [CSP-J 2022] 上升点列(DP)
    题目传送门解题思路首先先讲这些点按照  从小到大排序。然后,很容易想到设  表示到第  个点已经放了  个点的最长上升序列的长度。所以,我们可以从前面的点转移(注意要判断一下 是否符合,因为我们只按照了 排序);于是,手推一下可以整出这样一个转移方程:其中  是......