• (序列型dp)打劫房屋


    假设你是一个专业的窃贼,准备沿着一条街(n个房屋)打劫房屋。每个房子都存放着特定金额的钱ai。你面临的唯一约束条件是:相邻的房子装着联系的防盗系统,且当相邻的两个房子同一天被打劫时,该系统会自动报警。
    给定房屋数量n,给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,你最多可以得到多少钱 在不触动报警装置的情况下。
    输入样例:
    8
    1, 9, 2, 6, 8, 5, 10, 4
    输出样例:
    27
     
    暴力dfs:
    #include<iostream>
    #include<string.h>
    #include<math.h>
    
    using namespace std;
    int n,m,v; 
    long ans;
    int mod=1e9+7;
    int dp[105][105],aa[105];
    bool vis[105]; 
    
    void dfs2(int pos,int cot,int s){
        if(pos==n+1){
            if(ans<s){
                ans=s;
            }
            return;
        }
        if(cot==0){
            dfs2(pos+1,1,s+aa[pos]);
        }
        dfs2(pos+1,0,s);
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>aa[i];
        } 
        dfs2(1,0,0);
        cout<<ans;
        return 0;
    }

    dp解法:

    #include<iostream>
    #include<string.h>
    #include<math.h>
    
    using namespace std;
    int n,m,v; 
    long ans;
    int mod=1e9+7;
    int dp[105],aa[105];
    bool vis[105]; 
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>aa[i];
        } 
        dp[0]=0;                                        //我们设房子从1开始 第0个房子 肯定没法偷  
        dp[1]=aa[1];
        for(int i=2;i<=n;i++){                         //首先明白dp[i]表示选了的和 
            dp[i]=max(dp[i-1],dp[i-2]+aa[i]);          //这个转移方程的逻辑是 选不选aa[i]的问题  则要看aa[i-1]是否被选了 
        }                                              //若是aa[i-1]已经选了 就只能不选a[i] dp[i]=dp[i-1] 但是也可以不从i-1选aa[i] 从dp[i-2]选 dp[i]=dp[i-2]+aa[i]
        cout<<dp[n];                                   //若是aa[i-1]没选  a[i]选不选都可     dp[i]=dp[i-1] 或dp[i]=dp[i-2]+aa[i]   
        return 0;
    }

    升级版本:还是原问题,加了一个条件一条街上的首尾两个房子是相连的

    输入样例:

    3

    3 6 4

    输出样例:

    6

    暴力dfs:

    #include<iostream>
    #include<string.h>
    #include<math.h>
    
    using namespace std;
    int n,m,v; 
    long ans;
    int mod=1e9+7;
    int dp[105][105],aa[105];
    bool vis[105]; 
    void dfs(int pos,int s){
        if(pos==n+1){
            if(ans<s){
                ans=s;
            }
            return;
        }
        if(vis[pos-1]!=1&&vis[(pos+1)%n]!=1){
            vis[pos]=1;
            dfs(pos+1,s+aa[pos]);
            vis[pos]=0;
        }
        dfs(pos+1,s);
    }
    
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>aa[i];
        } 
        dfs(1,0);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    阿里云证书nginx无法访问带点的路径
    升级阿里云服务器文案
    html模板结合JS替换函数,生成新的记录
    企业使命、原景、战略、战略目标 详解
    Android之Handler用法总结【转】
    android activity的常用代码:关闭、传值、返回值、回调、网页、地图、短信、电话
    PHP十进制转36进制的函数
    [转]仓库管理必须知道的的50条重要知识
    [转]关于项目管理、软件开发的一些思考
    PHP5.5安装PHPRedis扩展
  • 原文地址:https://www.cnblogs.com/xusi/p/12498796.html
Copyright © 2020-2023  润新知