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];
}
};
芜湖 又轻松搞定一题~ _~
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;
}