数塔问题:
题目:
设有一个三角形的数塔,顶点为根结点,每个结点有一个整数值。从顶点出发,可以向左走或向右走,请找出一条路径,使路径之和最大,只要输出路径的和。
解析:
这道题
是很经典的动态规划
有的同志可能会问
用别的方法不好吗
下面我给大家来看看
别的方法的
翻车现场!!!∑(゚Д゚ノ)ノ
(1)深度优先搜索(穷举):从根结点开始,将所有可能的路径求和,找出最大值。
N=1,P=1
N=2,P=2
N=3,P=4
……
N=K,P=2^(K-1)
例如:N=50,P=2^49=500万亿条路径。
算法复杂度:O(2^(N-1))
(2)深度优先搜索(递归):
存在的问题:出现重复子问题,需要解决重复计算问题。
(3)贪心算法:
根据贪心算法法,得出的解为:13-11-21;而实际上最优解应为:13-8-40。
贪心算法往往得不到最优解。
不忍直视!!!∑(゚Д゚ノ)ノ
动态规划的题目
一般有两点
1、重复子问题
2、最优子结构
这道题完全符合以上两点
在输入的时候
是这样输入的:
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
从倒数第二行
往第一行推
每一行
从左到右推
每一个
都加等于这个数下面的值或右下角的值中大的那一个
算到最后
最上面的值就是最大的
下面附上代码
代码:
#include<bits/stdc++.h>
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int n,a[1000][1000],b[1000][1000];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
{
cin>>a[i][j];
b[i][j]=a[i][j];
}
for(int i=n-1;i>=1;i--)
for(int j=1;j<=i;j++)
{
b[i][j]=max(b[i+1][j],b[i+1][j+1])+a[i][j];
}
cout<<b[1][1];
return 0;
}
积分:
题目:
卡卡西和小朋友们做完了烧脑的数字游戏, 决定放松一下,他们来到了万达乐园, 乐园中有很多的游玩项目, 每玩一个项目就能获取一定的体验积分, 不同的项目产生不同的体验积分, 假设乐园所有的游乐项目正好排成一排, 并且游客们不能游玩任意相邻的两个项目,那么卡卡西如何挑选游玩项目, 使得这次万达行他能获得最多的体验积分值呢。
解析:
这道题
十分的像01背包
这道题的重点只有一个
玩还是不玩
我们可以将答案放在f数组里
一点一点假设
假设只玩第一个、假设只玩第一个和第二个、假设只玩第一个和第二个和第三个
一点一点进行计算
每放一个之前我们都要思考
如果放了f[i]
就只能放f[i-2]
否则
就放f[i-1]
这样一点一点的算
最终
就会算出最大值
所以这道题的DP方程是
f[i]=max(f[i-1],f[i-2]+f[i]);
下面附上代码:
代码:
#include<bits/stdc++.h>
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int a[1000],n,f[1000];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
f[1]=a[1];
for(int i=2;i<=n;i++) f[i]=max(f[i-1],f[i-2]+a[i]);
cout<<f[n];
return 0;
}
拜拜!!!