試題 演算法提高 天天向上 dp

2022-08-14 22:03:08 字數 1740 閱讀 7895

問題描述

a同學的學習成績十分不穩定,於是老師對他說:「只要你連續4天成績有進步,那我就獎勵給你一朵小紅花。」可是這對於a同學太困難了。於是,老師對他放寬了要求:「只要你有4天成績是遞增的,我就獎勵你一朵小紅花。」即只要對於第i、j、k、l四天,滿足i輸入格式

第一行乙個整數n,表示總共有n天。第二行n個數,表示每天的成績wi。

輸出格式

乙個數,表示總共可以得到多少朵小紅花。

樣例輸入

61 3 2 3 4 5

樣例輸出

6資料規模和約定

對於40%的資料,n<=50;

對於100%的資料,n<=2000,0<=wi<=109。

思路:分析:

我們將 dp[i][j] 定義為以a[i]為起點,一直到陣列結束為止,所有遞增序列長度為j的序列的個數。

以陣列 1 3 2 3 4 5為例:

dp[3][2]表示從第二個3為起始,一直到5,遞增序列長度為2的個數。容易知道,滿足這樣的序列有2個,34 和 35。所以dp[3][2]=2;

有了上述的定義,我們就可以得出以下遞推公式

dp[i][j]= ∑dp[k][j-1] (k>i,a[k]>a[i])

現在,我們只要確定了邊界條件,就可以使用動態規劃來解決這個問題了。

容易知道 dp[n-1][1]是邊界條件,值為1。

為了讓各位讀者對動態規劃的過程有更形象的了解,我就以1 3 2 3 4 5 為例,列出開頭的幾個步驟:

初始: dp[5][1]=1,其餘dp[i][j]=0;

第二步 : dp[4][1]=1; dp[4][2]=dp[5][1]=1;

第三步: dp[3][1]=1; dp[3][2]=dp[4][1]+dp[5][1]=2; dp[3][3]=dp[4][2]=1;

第四步:dp[2][1]=1; dp[2][2]=dp[5][1]+dp[4][1]+dp[3][1]=3; dp[2][3]=dp[3][2]+dp[4][2]=3; dp[2][4]=dp[3][3]=1;

第五步: dp[1][1]=0; dp[1][2]=dp[4][1]+dp[5][1]=2 (a[k]要大於a[i])

dp[1][3]=dp[4][2]=1;

第六步: dp[0][1]=1; dp[0][2]=dp[1][1]+dp[2][1]+dp[3][1]+dp[4][1]+dp[5][1]=5; … dp[0][4]=dp[1][3]+dp[2][3]+dp[3][3] =1+3+1=5;

dp[i][4]中儲存的就是,從i開始,一直到結束,遞增序列長度為4的序列的個數。

因此,只要計算所有的dp[i][4]的和即可。

注意:要long  long,否則只會通過40%的樣例

**:

#include#include

#include

using

namespace

std;

typedef

long

long

ll;const

int maxn = 2001

;ll a[maxn],dp[maxn][5];

intmain()

memset(dp,

0,sizeof

(dp));

for(int i=n;i>=1;i--)}}

ll sum=0

;

for(int i=1;i<=n;i++)

cout

return0;

}

演算法提高 天天向上

問題描述 a 同學的學習成績十分不穩定,於是老師對他說 只要你連續 4 天成績有進步,那我就獎勵給你一朵小紅花。可是這對於 a 同學太困難了。於是,老師對他放寬了要求 只要你有 4 天成績是遞增的,我就獎勵你一朵小紅花。即只要對於第 i j k l 四天,滿足 i j k l 並且對於成績 wi w...

藍橋杯 演算法提高 天天向上

資源限制 時間限制 1.0s 記憶體限制 256.0mb 問題描述 a同學的學習成績十分不穩定,於是老師對他說 只要你連續4天成績有進步,那我就獎勵給你一朵小紅花。可是這對於a同學太困難了。於是,老師對他放寬了要求 只要你有4天成績是遞增的,我就獎勵你一朵小紅花。即只要對於第i j k l四天,滿足...

天天向上 冬天

最近發現自己越來越痛恨睡懶覺,尤其是週末睡懶覺。還記得以前一到週末恨不得能睡到吃中飯。誰要是敢打擾我睡懶覺,我跟誰急。而最近不知道從什麼時候開始,週末不再喜歡睡懶覺,不是不困,其實也很睏,但是總覺的挺浪費時間的,很多事情沒做一天一晃就過去了。有一種時不我待的嚴重的緊迫感。很多事情要做,多的有點不知道...