情形一
題目**(
題面大概意思就是要找到最大和的子數列,並且輸出其和,其起始索引+1,其終止索引+1
做這道題時,我一開始的思路是
直接暴力遍歷找到所求解
上**
#
define
_crt_secure_no_warnings
#include
using
namespace std;
int p[
100005];
intmain()
int sum = int_min;
int begin =
0, end =0;
for(
int k =
0; k < n; k++)}
} cout <<
"case "
<< i +
1<<
":"<< endl;
cout << sum <<
" "<< begin +
1<<
" "<< end +
1<< endl;
if(i != t -
1)cout << endl;
}return0;
}
**提交後,果然wa
感覺應該是超時了,整個程式時間複雜度快有o(n^3)了,哎,不超時才怪
baidu了下人家的**,看了一下人家的思路分析
假設有n個數,p1,p2…pn 用數學歸納法
那麼以p1為結尾的子數列有
以p2為結尾的子數列有
以p3為結尾的子數列有
…以此類推
則該問題簡化成求n組子數列中n個子子數列中的最大值
我用dp表示
對於p1:dp1=p1;
對於p2:dp2=max(p1+p2,p2)=max(dp1+p2,p2);
對於p3:dp3=max(p1+p2+p3,p2+p3,p3)=max(dp2+p3,p3);
…對於pn:dpn=max(dpn-1+pn,pn);
由此 問題得解
上ac**
#
define
_crt_secure_no_warnings
#include
#include
#include
using
namespace std;
int p[
100005];
intmain()
int dp = p[0]
;int max = dp;
int begin =
0, end =0;
for(
int j =
1; j < n; j++)}
int tmp =0;
for(
int k = end; k >=
0; k--)}
cout <<
"case "
<< lp +
1<<
":"<< endl;
cout << max <<
" "<< begin+
1<<
" "<< end+
1<< endl;
if(lp != t -
1)cout << endl;
}return0;
}
這道題 我其實提交了挺多遍的,每次都沒發現那個坑在哪
最後一次
哎 傻了
題目要求是在兩個輸出結果之間再endl一下,沒說在每個結果endl啊
情形二
題目大意是找到所給序列中遞增子串行的最大和
與情形一不同,該題並未要求序列連續,但是核心演算法與上題無差
首先建立乙個dp陣列,p為輸入資料的陣列
dp[0]=p[0]
一系列操作後,得到n個dp,最後直接sort就ok,輸出dp陣列中最後乙個元素
核心**
memset
(dp,0,
sizeof
(dp));
int sum = int_min;
for(
int j =
0; j < n; j++)}
}sort
(dp, dp + n)
; cout << dp[n -1]
<< endl;
上述兩種題型應該屬於dp入門級別了,繼續加油 dp程式實踐
有這樣一道題,稱為數塔。font size 在講述dp演算法的時候,乙個經典的例子就是數塔問題,它是這樣描述的 有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?已經告訴你了,這是個dp的題目,你能ac嗎?輸入資料首先包括乙個整數c,表示測試例項的個...
排序演算法實踐
那天閱讀 之美 這本書的章節,寫個程式試試其中的排序演算法的例子,執行成功後,突然想試試和vc9自帶的 stl sort函式比較一下,測試結果出乎我所料,這個例子比stl 的sort函式一般快上3 4倍之多,覺得很是奇怪,檢查了一下,發現應該是debug版的原因,切換到release版再測,對於小資...
排序演算法實踐
輸入有兩行,第一行是乙個正整數,表示有n個同學參與調查 n 第二行有 個用空格隔開的正整數,為每本圖書的 號 假設圖書的isbn號在 1 1000之間 輸出有兩行,第一行是乙個正整數k,表示需要買多少本書。第二行是k個用空格隔開的正整數,為從小到大已排序的需要購買的圖書的isbn號。先排序,再去重。...