蓝桥杯-算法提高-天天向上-DP
- 问题描述
A同学的学习成绩十分不稳定,于是老师对他说:“只要你连续4天成绩有进步,那我就奖励给你一朵小红花。”可是这对于A同学太困难了。于是,老师对他放宽了要求:“只要你有4天成绩是递增的,我就奖励你一朵小红花。”即只要对于第i、j、k、l四天,满足i<j<k<l并且对于成绩wi<wj<wk<wl,那么就可以得到一朵小红花的奖励。现让你求出,A同学可以得到多少朵小红花。 - 输入格式
第一行一个整数n,表示总共有n天。第二行n个数,表示每天的成绩wi。 - 输出格式
一个数,表示总共可以得到多少朵小红花。 - 样例输入
6
1 3 2 3 4 5 - 样例输出
6 - 数据规模和约定
对于40%的数据,n<=50;
对于100%的数据,n<=2000,0<=wi<=109。 - 解题思路:
参考蓝桥杯 算法提高 天天向上 c++ 动态规划
满足条件①天数是递增的②对应的成绩是递增的,就可以获得一朵小红花。
dp[i][j]:从第i天开始,j天内,能获得的小红花数。
所以,初始化dp[i][1]=1;
当满足score[j]>score[i],j>i的条件下:
dp[i][2]=dp[j][1](其中,i<j<=n);
dp[i][3]=dp[j][2](其中,i<j<=n);
dp[i][4]=dp[j][3](其中,i<j<=n);
只需要求4天内满足条件的小红花数,所以,最后再求一下所有的dp[i][4]的和就好了。 - AC代码:
#include<iostream>
using namespace std;
int n;
long long score[2002];
long long dp[2002][5];
long long ans=0;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>score[i];
dp[i][1]=1;
}
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n;j++){
if(score[j]>score[i]){
dp[i][2]+=dp[j][1];
dp[i][3]+=dp[j][2];
dp[i][4]+=dp[j][3];
}
}
}
for(int i=1;i<=n;i++){
ans+=dp[i][4];
}
cout<<ans<<endl;
return 0;
}