-2 6 -1 5 4 -7 2 3html
求連續的子數列最大和。ios
根據遞歸的思路想:f(n) = max{ f(n-1) + num[n], num[n] }web
對於每個高度h[i],搜索它能到達的最左,和最右,最大面積Smax = Max{ i | 面積Si = (最右 - 最左 + 1) *h[i] }數組
這樣的時間複雜度爲O(n^2),必超時ide
舉例 2,3,4,5ui
要判斷2能到達最右的位置,不須要循環比較,只須要知道3能到達的最右是哪裏,由於若3能到達的位置,2必然也能到達spa
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 5 int main() 6 { 7 int n; 8 while(scanf("%d", &n) && n) 9 { 10 long long h[100007]; 11 long long l[100007]; 12 long long r[100007]; 13 for(int i=1;i<=n;i++) 14 { 15 scanf("%lld", &h[i]); 16 l[i] = r[i] = i; 17 } 18 h[0] = h[n+1] = -1; 19 for(int i=1;i<=n;i++) 20 { 21 while(h[i] <= h[l[i]-1]) { 22 l[i] = l[l[i]-1]; 23 } 24 } 25 for(int i=n;i>=1;i--) 26 { 27 while(h[i] <= h[r[i]+1]) { 28 r[i] = r[r[i]+1]; 29 } 30 } 31 long long ans = 0; 32 for(int i=1;i<=n;i++) 33 { 34 ans = ans > (r[i]-l[i]+1)*h[i] ? ans : (r[i]-l[i]+1)*h[i]; 35 } 36 printf("%lld\n",ans); 37 } 38 }
第一道本身作出來的DP!!!記念合影,你沒聽錯我就是這麼菜3d
給你一個非負整數num,求從0到num的num+1個數中,每一個數二進制表示的1的個數,返回一個數組code
就是dp嘛,暴力的辦法就是for from 0 to num,每一個數的每個二進制位比較,設二進制位最壞長度爲31位,那麼複雜度就是O(31*n)htm
其中大量重複計算,因此用動態規劃解決,自底向上
1 class Solution { 2 public: 3 vector<int> countBits(int num) { 4 vector<int>dp(num+1); 5 dp.resize(num+1); 6 dp[0] = 0; 7 for(int i=1;i<=num;i++) 8 { 9 if((i & 1) == 0) 10 dp[i] = dp[i>>1]; 11 else 12 dp[i] = dp[i>>1] + 1; 13 } 14 return dp; 15 } 16 };
給你一個序列arr = {}
請你求出它的一個子集,要求,子集和最大,且子集的元素在原序列終不能相鄰
入門DP
對於每個數,dp[i] = max{ dp[i-1], dp[i] + arr[i-1] }
那麼就和斐波那契有點像了
給你一個序列arr = {},和一個數S,問你序列裏的數能不能組成S
又是簡單的選和不選問題
這個有點難想,參考連接:
uim
拉着基友小A
到了一家……餐館,很低端的那種。
uim
指着牆上的價目表說:「隨便點」。
不過uim
因爲買了一些書
,口袋裏只剩M元(M≤10000)。
餐館雖低端,可是菜品種類很多,有N種(N≤100),第i種賣a元(ai≤1000)。因爲是很低端的餐館,因此每種菜只有一份。
小A
奉行「不把錢吃光不罷休」,因此他點單必定恰好吧uim
身上全部錢花完。他想知道有多少種點菜方法。
思路:和裸的價值+容量的01揹包不一樣,原來是求可放入揹包且價值最大化,這個是必須裝滿揹包,求有多少種方案。
根據題意設數組dp[i][j]爲前i種菜品剛好花費j元的點菜方法數。那麼,考慮第i種菜點或不點,若不點,則說明前i-1種菜,已經剛好花費j元;若點,則說明前i-1種菜,花費j-ai元,這樣,在點完第i種菜後,剛好花費j元。
所以容易得出公式
dp[i][j] = dp[i-1][j] + dp[i-1][j-ai]
然而不少人想到這裏之後就不知道接下來怎麼作了。(好比說我)
可是在看到"j - ai"後,應該能想到,對j - ai的狀況進行枚舉。
若j > ai,則和上式同樣。
若j < ai,則說明第i道菜,壓根就買不起,所以dp[i][j] = dp[i-1][j]。
若j == ai,那麼說明能夠只點這一道菜做爲一種新的方案,dp[i][j] = dp[i-1][j] + 1。
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 using namespace std; 5 6 int dp[103][10003] = {0}; 7 int price[103]; 8 9 int main() 10 { 11 int n, m; 12 scanf("%d%d", &n, &m); 13 for(int i=1;i<=n;i++) { 14 scanf("%d", &price[i]); 15 } 16 for(int i=1;i<=n;i++) { 17 for(int j=1;j<=m;j++) { 18 if (j == price[i]) 19 dp[i][j] = dp[i-1][j] + 1; 20 else if (j > price[i]) 21 dp[i][j] = dp[i-1][j] + dp[i-1][j - price[i]]; 22 else 23 dp[i][j] = dp[i-1][j]; 24 } 25 } 26 printf("%d\n", dp[n][m]);