ccpc河北大學生程序設計競賽dp小總結

近期題目來自校賽,賽前訓練,省賽熱身,河北ccpc正式比賽。

題目一:

題目描述:

由于第m個臺階上有好吃的薯條,所以薯片現在要爬一段m階的樓梯.
薯片每步最多能爬k個階梯,但是每到了第i個臺階,薯片身上的糖果都會掉落ai個,現在問你薯片至少得掉多少糖果才能得到薯條?

輸入:

多組數據輸入,每組數據第一行輸入兩個數字m(1<m<=1000),k(1<=k<m),接下來有m行,每一行輸入ai(0<ai<=1000),表示第i個臺階會掉落的糖果.

輸出:

對于每組數據,輸出至少要犧牲的糖果數.

樣例輸入

5 2
1 2 3 4 5
6 2
6 5 4 3 2 1

樣例輸出

9
9

分析:經過的數字全部加起來,為一個累加和,求最小累加和

遞推關系:

定義f(n)為必須到第n個臺階的最少累加和

分析可以如何得到f(n),我們通過跳一步,可以怎么跳到第n個臺階呢?

可以從第n-1個臺階跳到這里,可以n-2,n-3......n-k。

也就是說,

f(n)=an+min(f(n-1),f(n-2),......f(n-k))

必須到第n個臺階的最少累加和,就等于能跳到這里的所有位置中,最小的那個f(),跳過來(也就是加上本身)。

注意:前k個臺階可以從起點直接跳過來,貪心思想,經過任何多余的數字都不會是最優解。所以前k個f(n)直接賦值an.

也可以維持單調隊列把時間降到線性,不過o(n*k)已經足夠過了。

?

題目二:

題目描述:

JiangYu的小金庫是一個三維立體的空間,大小為XYZ,里面每個位置都藏著各種價值的寶物,既然是寶物價值自然非同一般,可正可負。

可惡的花花得知了這一切,想要偷走其中的珍寶們。

可是Jiangyu的小金庫安保措施十分嚴密,花花只有一次行動的機會,他決定偷走一個價值盡可能大的長方體區間。

那么他最大能偷走多少錢的寶物呢?

輸入:

第一行給出三個正整數 X,Y,Z

第二行一個整數n, 寶藏的數量

接下來n行,每行給出一個寶藏的位置xi,yi,zi, 以及價值ci

保證寶藏位置不重復。 (1 \leq X,Y,Z \leq 201≤X,Y,Z≤20)

(1 \leq n \leq X \times Y \times Z1≤n≤X×Y×Z)

(1 \leq xi \leq X1≤xi≤X)

(1 \leq yi \leq Y1≤yi≤Y)

(1 \leq zi \leq Z1≤zi≤Z)

(-1e9 \leq ci \leq 1e9?1e9≤ci≤1e9)

輸出:

一個整數,最大的價值

樣例輸入

2 2 2
8
1 1 1 10
1 1 2 9
1 2 1 10
1 2 2 9
2 1 1 10
2 1 2 9
2 2 1 -1
2 2 2 10

樣例輸出

66

?

https://blog.csdn.net/hebtu666/article/details/82788866這個網址寫了詳細講解哦。。。最好要看看

首先要明白一維最大子數組問題,設dp[n]的含義為必須以an結尾的數組中的最大和。

所以dp[n]就是,每一個以在n前面的結尾的最大值,加上an.

二維方法:轉化為一維來做。枚舉長度為原矩陣長度的所有矩陣。然后壓成一維來做。

時間:

因為有n個開頭,每個開頭有n-1,n-2......1個結尾,所以枚舉的時間復雜度為o(n^2)。

為了節省時間,利用預處理數組思想,定義長寬和原矩陣一樣的矩陣gg。

每列滿足第n列k行的值為sum(l[0][n]+l[1][n]....l[k][n]),可以o(n*m)做到(nm為長寬).然后枚舉到某矩陣的時候直接根據gg得出。整體做到o(n^2)枚舉并求和。然后按一維做。整體o(n^3)

三維:并沒有什么高大上的優化,也是枚舉每一個長寬固定的長方體,壓縮至二維,然后按二維做。

?

題目三:

熱身賽,并沒有原題,手打。

過的隊伍不多

一種動物,出生到死亡只有三年,即n年出生,n+3年死去。

出生一年以后可以生育,也就是n+1年開始生育,一年可以生一只寶寶。

定義第n年動物總數為an,給定n,返回an/a(n-1),最多保存小數點后十位

第一年有一只

思路一:定義f(n)為第n年新出生的動物個數,則f(n)=f(n-1)+f(n-2),前兩項為1,而每年的總數也就是三項求和而已。

每年出生的數量為1,1,2,3,5,8,13,21

每年總數就是1,2,4,10,16,26,42

發現是斐波那契數列

思路二:直接從總數入手,定義f(n)為第n年的總數

如何求出an/a(n-1):要看有多少動物能活到n年,活不到n年的也不能在第n年生育,活到n年的動物每人生一個,所以an就是二倍的能活到n年的動物。求此數方法很多,在此只說一個:

f(n-1)-(1/2)f(n-3)

去年的數量減去,去年還活著的今年就死了的數量。

這個數乘二,得出答案f(n)=2f(n-1)-f(n-3),其實本質還是斐波那契,因為f(n-1)=f(n-2)+f(n-3),帶入以后發現f(n)=f(n-1)+f(n-2)。

式子寫出來了,但是原題數據范圍是10^1000,不能一項一項推過去。

嘗試發現,幾十項之后,an/a(n-1)的十位小數之內都沒有變過,所以當數字較大時直接輸出第五十項即可。

本題結束

但是還有點別的東西想寫

?

斐波那契的美

萬物之美,總能找到斐波那契數列的規律。隨著n的增加,an/a(n-1)越來越接近黃金分割

手寫了求解過程。可能寫的不規范,但是就是表達這個意思。

?

只要數列滿足X(n) = X(n-1) + X(n-2),無論前兩個值是多少,都滿足黃金分割的條件,而斐波那契數列是最簡單的特例:前兩個元素均為1

數學家還發現了費馬大定理和這個數列的關系(費馬大定理的證明,三百五十年),并應用到諸多領域(比如加密)。有興趣自行了解。

?

題目四:

省賽,沒有原題。十六支隊伍過了這個題。

https://blog.csdn.net/hebtu666/article/details/79964233

參考我前面的文章,dp入門篇,那個會了這個就會。

參考萌新題

現場因為對c++不熟,沒敢壓空間,規規矩矩的寫了一遍,還因為多打了一行罰了時,跟智障一樣。。。

?

?

題目五

http://newoj.acmclub.cn/contests/1359/problem/6

題意:最長公共子序列,要求序列每個元素重復k次,比如1122重復兩次,111222重復三次。

輸入兩個字符串和k,輸出長度。

最長公共子序列的一個變形。。。

動態規劃。設dp[i][j]表示a串處理到i位置,b串處理到j位置的答案。預處理出從a串i位置向前數,第k個與i位置數
字相同的位置p[i],用相同方式處理出B串的q[i]。
則轉移方程為dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i-p[i]][j-q[j]]+1),其中第三種轉移必須在a[i]=b[j]的情況下轉移。

?

#include <bits/stdc++.h>
using namespace std;
int k,n,m,dp[1005][1005];
int a[1005],b[1005];
int pa[1005]={0},pb[1005]={0};
queue<int> q[1005];
int main()
{int ak; cin>>ak;while(ak--){for(int i=1;i<=n;i++)while(!q[i].empty()) q[i].pop();scanf("%d%d%d",&k,&n,&m);memset(dp,0,sizeof(dp));memset(pa,0,sizeof(pa));memset(pb,0,sizeof(pb));for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=m;i++) cin>>b[i];for(int i=1;i<=n;i++){q[a[i]].push(i);if(q[a[i]].size()==k){pa[i]=q[a[i]].front();q[a[i]].pop();}}for(int i=1;i<=n;i++)while(!q[i].empty()) q[i].pop();for(int i=1;i<=m;i++){q[b[i]].push(i);if(q[b[i]].size()==k){pb[i]=q[b[i]].front();q[b[i]].pop();}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){dp[i][j]=max(dp[i-1][j],dp[i][j-1]);if(a[i]==b[j] && pa[i]!=0 && pb[j]!=0)dp[i][j]=dp[pa[i]-1][pb[j]-1]+k;}}printf("%d\n",dp[n][m]);}return 0;
}

代碼都是比賽時候寫的,真的不想找來貼了。

?

最后總結經驗教訓:

?

注意細節,注意細節,注意細節

多種思路,多種思路,多種思路

遞歸關系自己推,比如背包,你要是看套路。。。Emmm。。就連套路都不會用了。

平時遞歸關系自己推,自己推,自己推。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445667.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445667.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445667.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c語言簡便實現鏈表增刪改查

注&#xff1a;單追求代碼簡潔&#xff0c;所以寫法可能有點不標準。 //第一次拿c開始寫數據結構&#xff0c;因為自己寫的&#xff0c;追求代碼量少&#xff0c;和學院ppt不太一樣。有錯請指出 #include <stdio.h> #include <stdlib.h> #include <string.h>…

第一次課 課上代碼

第一次課內容 學習心態及注意事項 信心 謙虛 腳踏實地 多動手 python簡介 代碼量少&#xff0c;簡介&#xff0c;易上手&#xff0c;語法要求不過于嚴格&#xff0c; Python 庫。 速度慢&#xff0c; 不可加密。 輸出、變量、輸入 數據類型&#xff1a;整數、浮點數…

計算機考研專業課只考一科的學校匯總

下列學校專業課只考1門 &#xff08;每項科目下的學校均按照最新學科評估結果由高到低進行排名&#xff09; C語言程序設計 1. 湖南大學 計算機技術&軟工專碩&#xff08;信息科學與工程學院&#xff09; 2. 中國海洋大學 計算機技術&#xff08;01計算機應用技術方向&am…

數組實現棧

學習了改進&#xff0c;利用define typedef比上次寫的鏈表更容易改變功能&#xff0c;方便維護&#xff0c;代碼更健壯。 大佬別嫌棄&#xff0c;萌新總是很笨&#xff0c;用typedef都想不到。 #include<stdio.h> #include<stdbool.h> #define maxsize 10 typede…

簡單暴力到dp的優化(中級篇)

下面再放三道我比較喜歡的&#xff0c;需要好好寫一下的題。 第一題比較水 1. White Cloud is exercising in the playground. White Cloud can walk 1 meters or run k meters per second. Since White Cloud is tired,it cant run for two or more continuous seconds. Whi…

第二次課 課上代碼

敲一遍&#xff0c;體會每行代碼想表達的意思。 第二講 創建.py文件 數據類型&#xff1a;布爾(and\or\not) 條件判斷語句(if elif else) 列表基礎操作&#xff08;特點、創建、增加元素、len()、下標、py切片&#xff09; >>> 5>4 True >>> 4>5 Fa…

第一次課 優秀作業展示

18級河北師大軟件編程訓練 很多同學非常認真的完成了作業&#xff0c;這里選出比較優秀的作業展示出來。 注&#xff1a;展示順序不是排名 為了尊重同學們的勞動成果&#xff0c;并沒有要代碼&#xff0c;只是截圖展示。 范天祚 &#xff08;傻兔子&#xff09; 熊靜祎&…

dp打開思路:HDU1029 HDU1087 HDU1176?HDU1257 POJ1458(水題不水)

題目&#xff1a;https://vjudge.net/contest/68966#overview HDU - 1029 題意&#xff1a;找出出現次數超過一半的數字 蠢思路&#xff1a;排序找中間 DP&#xff1a;掃一遍一個變量count記錄解出現的次數&#xff0c;是當前解就&#xff0c;否則--&#xff0c;count為負就…

dp打開思路2:POJ2533 HDU1114 HDU1260 HDU1160(水題不水)

題目&#xff1a;https://vjudge.net/contest/68966#overview POJ2533 最長上升子序列&#xff0c;很平常的題&#xff0c;但是維持單調隊列二分還是值得一貼的&#xff0c;O(nlogn) 關鍵思想&#xff1a;出現在單調隊列里的數都在當前接收的數之前&#xff0c;所以找到最小…

二分查找及一般拓展總結

二分-不止是查找哦 二分過程&#xff1a;首先&#xff0c;假設表中元素是按升序排列&#xff0c;將表中間位置記錄的關鍵字與查找關鍵字比較&#xff0c;如果兩者相等&#xff0c;則查找成功&#xff1b;否則利用中間位置記錄將表分成前、后兩個子表&#xff0c;如果中間位置記…

第三次課 課上代碼

這次可能比較簡短&#xff0c;這樣也好&#xff0c;可讀性比較強。 別問我為什么&#xff0c;我不會告訴你們我把代碼關了的哼哼。 簡單復習、注意事項及小知識強調講解 作業講解 列表的遍歷 For循環&#xff08;這個參考切片&#xff0c;視頻有詳細講解&#xff0c;一樣的…

排序算法基本介紹及python實現(含詳細注釋)

對數組排序可以說是編程基礎中的基礎&#xff0c;本文對八種排序方法做簡要介紹并用python實現。 代碼中注釋很全&#xff0c;適合復習和萌新學習。這是剛入學自己寫的&#xff0c;可能難免比不上標準的寫法&#xff0c;但是懶得改了。 文末會放和排序相關的基本拓展總結鏈接…

第二次作業 講解及展示

第二次作業&#xff0c;同學們雖然在認真完成&#xff0c;但是或多或少都出了一些錯誤&#xff0c;一班張婷&#xff0c;四班武儀人&#xff0c;六班楊澤宇&#xff0c;八班候雯潔&#xff0c;安錦陽&#xff0c;劉凈圓&#xff0c;這些同學完成的較為出色&#xff0c;錯誤較少…

深搜DFS\廣搜BFS 圖初步入門

首先&#xff0c;不管是BFS還是DFS&#xff0c;由于時間和空間的局限性&#xff0c;它們只能解決數據量比較小的問題。 深搜&#xff0c;顧名思義&#xff0c;它從某個狀態開始&#xff0c;不斷的轉移狀態&#xff0c;直到無法轉移&#xff0c;然后退回到上一步的狀態&#xf…

素數基本(埃氏篩法/線性篩法)

一、檢查n是否為素數 最簡單思路&#xff1a;所有可能的因數全部試一遍。 int gg(int n) {for(int i2;i<n;i){if((n%i)0)return 0;//有因數就不是素數咯}return 1; } 進一步思考&#xff1a;沒必要枚舉所有的數&#xff0c;每一個小于n^(1/2)的因數i&#xff0c;一定有一個大…

歐幾里得gcd/extend_gcd

正式敘述前還寫了一點自己的小感受。 問題&#xff1a;求兩個正整數a&#xff0c;b的最大公約數。 大神看來是很簡單的問題&#xff0c;但是對于去年夏天剛學python的我來說&#xff0c;這是個很難的問題&#xff0c;還記得當時一晚上睡不著都在想怎么快一點的求出最大公約數…

python基礎技巧總結(一)

最近總結一下python基礎知識&#xff0c;就暫時棄坑了。 本文總結只屬于python的一些騷操作。。。 后面文章自行去博客學習交流 原地交換 Python 提供了一個直觀的在一行代碼中賦值與交換&#xff08;變量值&#xff09;的方法 x, y 10, 20 print(x, y)x, y y, x print(x…

python基礎技巧總結(二)

一總結的鏈接&#xff1a; 好&#xff0c;我們繼續 一次性初始化多個變量 可以直接賦值&#xff1a; a,b,c,d1,2,3,4 可以利用列表&#xff1a; List [1,2,3] x,y,zList print(x, y, z) #-> 1 2 3 &#xff08;元素個數應與列表長度相同&#xff09; 打印模塊路徑 im…

python基礎技巧總結(三)

前兩篇文章&#xff1a; https://blog.csdn.net/hebtu666/article/details/81698235 https://blog.csdn.net/hebtu666/article/details/81698329 我們繼續總結&#xff1a; 開啟文件分享 Python 允許運行一個 HTTP 服務器來從根路徑共享文件&#xff0c;下面是開啟服務器的…

python基礎技巧總結(四)

前三期請到我博客里找 https://blog.csdn.net/hebtu666 我們繼續總結 except的用法和作用 try/except: 捕捉由PYTHON自身或寫程序過程中引發的異常并恢復 except: 捕捉所有其他異常 except name: 只捕捉特定的異常 except name, value: 捕捉異常及格外的數據(實例) exce…