(序列型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;
}
原文地址:https://www.cnblogs.com/xusi/p/12498796.html