0.爬楼梯:
int n;
::scanf("%d",&n);
int dp[n];
dp[0]=1;
dp[1]=2;
for (int i = 2; i < n; ++i) {
dp[i]=dp[i-1]+dp[i-2];
}
::printf("%d",dp[n-1]);
1.最大子列和:
int n;
::scanf("%d",&n);
int arr_text[n];
for (int i = 0; i < n; ++i) {
::scanf("%d",&arr_text[i]);
}
int dp[n];
dp[0]=arr_text[0];
int res=dp[0];
for (int i = 1; i < n; ++i) {
dp[i]= max(dp[i-1]+arr_text[i],arr_text[i]);
res= max(res,dp[i]);
}
::printf("%d",res);
用res记录最大;
2.三角数:
::scanf("%d",&n);
for (int i = 1; i < n+1; ++i) {
for (int j = 1; j < 1+i; ++j) {
::scanf("%d",&a[i][j]);
}
}
dp[1][1]=a[1][1];
int res=dp[1][1];
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
dp[i][j]= max(dp[i-1][j-1]+a[i][j],dp[i-1][j]+a[i][j]);
}
}
for (int i = 1; i <= n; ++i) {
res= max(res,dp[n][i]);
}
::printf("%d",res);
return 0;
迭代,在最后一行找最大
摆花:
int n,m;
int mod=1000007;
int f[110][110];//i种花,摆j盆
::scanf("%d %d",&n,&m);
int a[n];
for (int i = 1; i <= n; ++i) {
::scanf("%d",&a[i]);
}
for (int i = 1; i < n; ++i) {
f[i][0]=1; // j=0可摆放0;那么只有1种情况
}
for (int i = 0; i <= a[1]; ++i) {
f[1][i]=1; // i=1一种花;只有一种情况:摆到a[i]
}
for (int i = 2; i <=n ; ++i) {
for (int j = 1; j <= m; ++j) {
for (int k = 0; k <= a[i]&&k<=j; ++k) {
f[i][j]=(f[i][j]+f[i-1][j-k])%mod;
//状态转移,即对前i种花可摆放情况迭代计算
//k从0开始,直到j-a[i]摆完,显然作为极限总方案数必须大于0
}
}
}
::printf("%d",f[n][m]);
严不严格递增子列:
int n;
::scanf("%d",&n);
int L[n];
for (int i = 0; i < n; ++i) {
::scanf("%d",&L[i]);
}
int dp[n];
for (int i = 0; i < n; ++i) {
dp[i]=1;
}
for (int i = 1; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if((L[i]>=L[j])&&(dp[j]>=dp[i])){
dp[i]=dp[j]+1;
}
}
}
int res=1;
for (int i = 0; i < n; ++i) {
res=((res>=dp[i])?res:dp[i]);
}
::printf("%d",res);
开辟dp,存储以i结尾的子列最大长度.一遍遍遍历中得到所有最大长度,通过循环初始化.
拆数字:
int n;
::scanf("%d",&n);
int dp[100]={0};
dp[0]=0;
dp[1]=0;
dp[2]=1;
for (int i = 3; i <= n; ++i) {
for (int j = 1; j < i; ++j) {
dp[i]= max(j*(i-j),j*dp[i-j],dp[i]);
}
}
::printf("%d",dp[n]);
dp[i]动态更新,不拆,拆两个,拆多个;0 0 1 2 4 6 9 12 18 27 36
能量聚合,区间dp:
#include<iostream>
using namespace std;
#include<stdio.h>
int max(int a,int b){
return a>b?a:b;
}
int main(){
int n;
::scanf("%d",&n);
int N=199;
int a[N]; // head
int dp[N][N]; //[区间]内合成的最大值
for (int i = 1; i <= n; ++i) {
::scanf("%d",&a[i]);
a[i+n]=a[i];
}
for (int i = 3; i <= n+1; ++i) { //length or number
for (int j = 1; j+i <= 2*n+1; ++j) { //start
int end=i+j-1;//end
for (int k = j+1; k < end; ++k) {
dp[j][end]= max(dp[j][end],dp[j][k]+dp[k][end]+a[j]*a[k]*a[end]);
}
}
}
int res=0;
for (int i = 1; i <= n; ++i) {
res= max(res,dp[i][i+n]);
}
::printf("%d",res);
}
暴力迭代.
沙丘,区间和,区间dp:
int min(int a, int b) {
return a < b ? a : b;
}
int main() {
int n;
::scanf("%d", &n);
int N = 310;
int a[N]; // heap
int dp[N][N]; //[区间]内合成的最大值
int sum[N];
memset(dp,0x3f, sizeof(dp)); // string.h
for (int i = 1; i <= n; ++i) {
::scanf("%d", &a[i]);
sum[i]=sum[i-1] + a[i];
dp[i][i]=0;
}
for (int i = 2; i <= n; ++i) { //length or number
for (int j = 1; j + i <= n + 1; ++j) { //start
int end = i + j - 1;//end
for (int k = j; k < end; ++k) {
dp[j][end]= min(dp[j][end],dp[j][k]+dp[k+1][end]+sum[end]-sum[j-1]);
}
}
}
::printf("%d", dp[1][n]);
}
n^3 暴力迭代