刷题记录----leetcode ,dp问题

48 篇文章 0 订阅
11 篇文章 0 订阅

dp解决:
1.leet-code 70. 爬楼梯

class Solution {
public:
    int climbStairs(int n) {
        int f[n+10];
        fill(f,f+n+10,0);
        f[1]=1;
        f[2]=2;
        for(int i=0;i<=n;i++){
           if(i>2) f[i]=f[i-1]+f[i-2];     
        }
        return f[n];    
        }
};

2.746. 使用最小花费爬楼梯

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int f[cost.size()+10];
        fill(f,f+cost.size()+10,0);
        f[0]=0;
        f[1]=cost[0];

        int f2[cost.size()+10];
        fill(f2,f2+cost.size()+10,0);
        f2[0]=0;
        f2[1]=0;
        f2[2]=cost[1];

        for(int i=2;i<cost.size()+1;++i){
            f[i]=min(f[i-1]+cost[i-1],f[i-2]+cost[i-2]);
            if(i>=3)f2[i]=min(f2[i-1]+cost[i-1],f2[i-2]+cost[i-2]);
        }

        int res=min(f[cost.size()],f2[cost.size()]);
        return res;
    }
};

3.面试题 08.01. 三步问题

class Solution {
public:
    int waysToStep(int n) {
        const int MOD=1000000007;
        int f[n+10];
        fill(f,f+n+10,0);
        f[0]=0;
        f[1]=1;
        f[2]=2;
        f[3]=4;
        for(int i=4;i<=n;i++){
            f[i]=((f[i-1]+f[i-2])%MOD+f[i-3])%MOD;
        }
        return f[n];
    }
};

4.打家劫舍

—感动第一个亲手写出来的稍微像样的题目—

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size()==0) return 0;
        if(nums.size()==1) return nums[0];
        int f[nums.size()+10];
        fill(f,f+nums.size()+10,0);
        f[0]=nums[0];
        f[1]=max(nums[0],nums[1]);
        for(int i=2;i<nums.size();++i){
            f[i]=max(f[i-2]+nums[i],f[i-1]);
        }
        return f[nums.size()-1];
    }
};

5.面试题 17.16. 按摩师

芜湖 又轻松搞定一题~ _~

class Solution {
public:
    int massage(vector<int>& nums) {
        if(nums.size()==0) return 0;
        if(nums.size()==1) return nums[0];
        int f[nums.size()+10];
        fill(f,f+nums.size()+10,0);
        f[0]=nums[0];
        f[1]=max(nums[0],nums[1]);

        for(int i=2;i<nums.size();i++){
            f[i]=max(f[i-1],f[i-2]+nums[i]);
        }
        return f[nums.size()-1];
    }
};

6.数字三角形

这题特别注意 初始化,如果我们输入的数据为负数,我们初始化的数据为0的,因为我们求的是最大,那么会用到我们认为不会取到的0,所以有错误,我们应该先初始化为最小值(或者比一般的负数小的值)

#include<iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N=500;

int n;
int arr[N+10][N+10];

int f[N+10][N+10];

int main(){
    cin>>n;
    memset(f,-1111,sizeof f);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            cin>>f[i][j];
        }
    }
    
    for(int i=2;i<=n;i++){
        for(int j=1;j<=i;j++){
            f[i][j]=max(f[i-1][j],f[i-1][j-1])+f[i][j];
        }
    }
    
    int res=0;
    for(int i=1;i<=n;i++){
        res=max(res,f[n][i]);
    }
    cout<<res;
    return 0;
}



7.朴素01背包

注意条件啊

#include <iostream>
#include <algorithm>
using namespace std;

const int N=1000;

int n,v;
int z[N+10];
int val[N+10];
int f[N+10][N+10];

int main(){
    cin>>n>>v;
    for(int i=1;i<=n;i++){
        cin>>z[i]>>val[i];
    }
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=v;j++){
            f[i][j]=f[i-1][j];
            if(z[i]<=j)  f[i][j]=max(f[i-1][j],f[i-1][j-z[i]]+val[i]);
        }
    }
    cout<<f[n][v];
    return 0;
}

8.朴素的完全背包

也是通过分析出来的

#include <iostream>
#include<algorithm>
using namespace std;

const int N=1000 ;


int n,v;
int z[N+10];
int f[N+10][N+10];
int val[N+10];

int main(){
    cin>>n>>v;
    for(int i=1;i<=n;i++){
        cin>>z[i]>>val[i];   
    }
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=v;j++){
            f[i][j]=f[i-1][j];
            for(int k=1;k*z[i]<=j;k++){
                f[i][j]=max(f[i][j],f[i-1][j-k*z[i]]+k*val[i]);
            }
        }
    }
    cout<<f[n][v]<<endl;
    return 0;
}

9.打家劫舍Ⅱ

房屋是一个环,第一间房子和最后一间房子互斥

class Solution {
    public int rob(int[] nums) {
        if(nums.length == 0) return 0;
        if(nums.length == 1) return nums[0];
        return Math.max(myRob(Arrays.copyOfRange(nums, 0, nums.length - 1)), 
                        myRob(Arrays.copyOfRange(nums, 1, nums.length)));
    }
    private int myRob(int[] nums) {
        int pre = 0, cur = 0, tmp;
        for(int num : nums) {
            tmp = cur;
            cur = Math.max(pre + num, cur);
            pre = tmp;
        }
        return cur;
    }
}

10.数字组合

写到这精神已经有点不太行了,竟然没看出来是01背包的变形。

#include <iostream>
#include <algorithm>
using namespace std;

const int N=1000;

int n,v;
int z[N+10];
int f[N+10][N+10];

int main(){
    cin>>n>>v;
    for(int i=1;i<=n;i++){
        cin>>z[i];
    }
    for(int i=0;i<=n;++i){
        f[i][0]=1;
    }
    

    for(int i=1;i<=n;i++){
        for(int j=1;j<=v;j++){
            f[i][j]+=f[i-1][j];
            if(j-z[i]>=0) f[i][j]+=f[i-1][j-z[i]];
        }
    }
    cout<<f[n][v];
    return 0;
}

11.糖果 (dp)

01 背包问题的变形

#include <iostream>
#include <cstring>
using namespace std;

int n,k;
int arr[100+10];
//前i个物品j
int f[100+10][100+10];

int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    memset(f,-0x3f,sizeof f);
    f[0][0]=0;
    //前i个物品
    for(int i=1;i<=n;i++){
        //k
        for(int j=0;j<k;j++){
           f[i][j]=max(f[i-1][j],f[i-1][(j+k-arr[i]%k)%k]+arr[i]); 
        }
    }
    int res=0;
    cout<<f[n][0];
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值