HDU 動態規劃 46道題目的學習
HDU 動態規劃(46道題目)
原作者網址:http://www.cppblog.com/doer-xee/archive/2010/01/28/102629.html#Post
別人看到的只有結果,過程只有自己知道。
Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955
揹包;第一次做的時候把概率當做揹包(放大100000倍化為整數):在此範圍內最多能搶多少錢 最腦殘的是把總的概率以為是搶N家銀行的概率之和… 把狀態轉移方程寫成了f[j]=max{f[j],f[j-q[i].v]+q[i].money}(f[j]表示在概率j之下能搶的大洋);
正確的方程是:f[j]=max(f[j],f[j-q[i].money]*q[i].v) 其中,f[j]表示搶j塊大洋的最大的逃脫概率,條件是f[j-q[i].money]可達,也就是之前搶劫過;
始化為:f[0]=1,其餘初始化為-1 (搶0塊大洋肯定不被抓嘛)
最大報銷額 http://acm.hdu.edu.cn/showproblem.php?pid=1864
又一個揹包問題,對於每張發票,要麼報銷,要麼不報銷,0-1揹包,張數即為揹包;
轉移方程:f[j]=max(f[j],f[j-1]+v[i]);
噁心地方:有這樣的輸入資料 3 A:100 A:200 A:300
最大連續子序列 http://acm.hdu.edu.cn/showproblem.php?pid=1231
狀態方程:sum[i]=max(sum[i-1]+a[i],a[i]);最後從頭到尾掃一邊
也可以寫成:
Max=a[0];
Current=0;
for(i=0;i<n;i++)
{
if(Current<0)
Current=a[i];
else
Current+=a[i];
if(Current>Max)
Max=Current;
}
max sum http://acm.hdu.edu.cn/showproblem.php?pid=1003
同上,最大連續子序列
Largest Rectangle http://acm.hdu.edu.cn/showproblem.php?pid=1506
對於每一塊木板,Area=height[i]*(j-k+1) 其中,j<=x<=k,height[x]>=height[i];找j,k成為關鍵,一般方法肯定超時,利用動態規劃,如果它左邊高度大於等於它本身,那麼它左邊的左邊界一定滿足這個性質,再從這個邊界的左邊迭代下去
for(i=1;i<=n;i++)
{
while(a[l[i]-1]>=a[i])
l[i]=l[l[i]-1];
}
for(i=n;i>=1;i--)
{
while(a[r[i]+1]>=a[i])
r[i]=r[r[i]+1];
}
City Game http://acm.hdu.edu.cn/showproblem.php?pid=1505
1506的加強版,把2維轉換化成以每一行底,組成的最大面積;(注意處理連續與間斷的情況);
Bone Collector http://acm.hdu.edu.cn/showproblem.php?pid=2602
簡單0-1揹包,狀態方程:f[j]=max(f[j],f[j-v[i]]+w[i])
Super Jumping http://acm.hdu.edu.cn/showproblem.php?pid=1087
最大遞增子段和,狀態方程:sum[j]=max{sum[i]}+a[j]; 其中,0<=i<=j,a[i]<a[j]
命運http://acm.hdu.edu.cn/showproblem.php?pid=2571
狀態方程:sum[i][j]=max{sum[i-1][j],sum[i][k]}+v[i][j];其中1<=k<=j-1,且k是j的因子
Monkey And Banana http://acm.hdu.edu.cn/showproblem.php?pid=1069
狀態方程:f[j]=max{f[i]}+v[j];其中,0<=i<=j,w[i]<w[j],h[i]<h[j]
Big Event in HDU http://acm.hdu.edu.cn/showproblem.php?pid=1171
一維揹包,逐個考慮每個物品帶來的影響,對於第i個物品:if(f[j-v[i]]==0) f[j]=0;
其中,j為逆序迴圈,且j>=v[i]
數塔http://acm.hdu.edu.cn/showproblem.php?pid=2084
自底向上:dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+v[i][j];
免費餡餅http://acm.hdu.edu.cn/showproblem.php?pid=1176
簡單數塔
自底向上計算:dp[i][j]=max(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1])+v[i][j];處理邊界
I Need A Offer http://acm.hdu.edu.cn/showproblem.php?pid=1203
簡單0-1揹包,題目要求的是至少收到一份Offer的最大概率,我們得到得不到的最小概率即可,狀態轉移方程:f[j]=min(f[j],f[j-v[i]]*w[i]);其中,w[i]表示得不到的概率,(1-f[j])為花費j元得到Offer的最大概率
FATE http://acm.hdu.edu.cn/showproblem.php?pid=2159
二維完全揹包,第二層跟第三層的要順序迴圈;(0-1揹包逆序迴圈);狀態可理解為,在揹包屬性為 {m(忍耐度), s(殺怪個數)} 裡最多能得到的經驗值,之前的揹包犧牲體積,這個揹包犧牲忍耐度跟個數
注意: 最後掃的時候 外層迴圈為忍耐度,內層迴圈為殺怪個數,因為題目要求出剩餘忍耐度最大,沒有約束殺怪個數,一旦找到經驗加滿的即為最優解;
狀態轉移方程為: f[j][k]=max(f[j][k],f[j-v[i]][k-1]+w[i]); w[i]表示殺死第i個怪所得的經驗值,v[i]表示消耗的忍耐度
How To Type http://acm.hdu.edu.cn/showproblem.php?pid=2577
用兩個a,b陣列分別記錄Caps Lock開與關時列印第i個字母的最少操作步驟;
而對於第i個字母的大小寫還要分開討論:
Ch[i]為小寫: a[i]=min(a[i-1]+1,b[i-1]+2);不開燈直接字母,開燈則先關燈再按字母,最後保持不開燈; b[i]=min(a[i-1]+2,b[i-1]+2);不開燈則先按字母再開燈,開燈則Shift+字母(比關燈,按字母再開燈節省步數),最後保持開燈;
Ch[i]為大寫: a[i]=min(a[i-1]+2,b[i-1]+2); b[i]=min(a[i-1]+2,b[i-1]+1)
最後,b[len-1]++,關燈嘛O(∩_∩)O~
Coins http://acm.hdu.edu.cn/showproblem.php?pid=2844
類似於HDU1171 Big Event In HDU,一維DP,可達可不達
Beans http://acm.hdu.edu.cn/showproblem.php?pid=2845
橫豎分別求一下不連續的最大子段和;
狀態方程: Sum[i]=max(sum[j])+a[i];其中,0<=j<i-1;
Largest Submatrix http://acm.hdu.edu.cn/showproblem.php?pid=2870
列舉a,b,c 最大完全子矩陣,類似於HDU1505 1506
Matrix Swapping II http://acm.hdu.edu.cn/showproblem.php?pid=2830
最大完全子矩陣,以第i行為底,可以構成的最大矩陣,因為該題可以任意移動列,所以只要大於等於height[i]的都可以移動到一起,求出height>=height[i]的個數即可,這裡用hash+滾動,先求出height[i]出現的次數,然後逆序掃一遍hash[i]+=hash[i+1];
最少攔截系統http://acm.hdu.edu.cn/showproblem.php?pid=1257
兩種做法,一是貪心,從後往前貪;二是DP;
if(v[i]>max{dp[j]}) (0<=j<len)
dp[len++]=v[i];
Common Subsequence http://acm.hdu.edu.cn/showproblem.php?pid=1159
經典DP,最長公共子序列
Len[i][j]={len[i-1][j-1]+1,(a[i]==b[j]); max(len[i-1][j],len[i][j-1])}
初始化的優化:
for(i=0;i<a;i++)
for(j=0;j<b;j++)
len[i][j]=0;
for(i=1;i<=a;i++)
for(j=1;j<=b;j++)
if(ch1[i-1]==ch2[j-1])
len[i][j]=len[i-1][j-1]+1;
else
len[i][j]=max(len[i-1][j],len[i][j-1]);
★ 搬寢室http://acm.hdu.edu.cn/showproblem.php?pid=1421
狀態Dp[i][j]為前i件物品選j對的最優解
當i=j*2時,只有一種選擇即 Dp[i-2][j-1]+(w[i]-w[i-1])^2
當i>j*2時,Dp[i][j] = min(Dp[i-1][j],Dp[i-2][j-1]+(w[j]-w[j-1])^2)
★ Humble Numbers http://acm.hdu.edu.cn/showproblem.php?pid=1058
如果一個數是Humble Number,那麼它的2倍,3倍,5倍,7倍仍然是Humble Number
定義F[i]為第i個Humble Number
F[n]=min(2*f[i],3*f[j],5*f[k],7*f[L]), i,j,k,L在被選擇後相互移動
(通過此題理解到陣列有序特性)
★ Doing Homework Again http://acm.hdu.edu.cn/showproblem.php?pid=1789
這題為貪心,經典題;
切題角度,對於每個任務要麼在截至日期前完成要麼被扣分;所以考慮每個人物的完成情況即可;由於每天只能完成一個任務,所以優先考慮分值較大的任務,看看該任務能不能完成,只要能完成,即使提前完成,佔了其他任務的完成日期也沒關係,因為當前任務的分值最大嘛,而對於能完成的任務能拖多久就拖多久,以便騰出更多時間完成其他任務;
How Many Ways http://acm.hdu.edu.cn/showproblem.php?pid=1978
兩種D法,一是對於當前的點,那些點可達;二是當前點可達那些點;
明顯第二種方法高,因為第一種方法有一些沒必要的嘗試;
Dp[i][j]+=Dp[ii][jj]; (map[ii][jj]>=兩點的曼哈頓距離)
值得優化的地方,每兩點的曼哈頓距離可能不止求一次,所以預處理一下直接讀取
珍惜現在 感恩生活http://acm.hdu.edu.cn/showproblem.php?pid=2191
每個物品最多可取n件,多重揹包;
利用二進位制思想,把每種物品轉化為幾件物品,然後就成為了0-1揹包
Piggy-Bank http://acm.hdu.edu.cn/showproblem.php?pid=1114
完全揹包;常規揹包是求最大值,這題求最小值;
只需要修改一下初始化,f[0]=0,其他賦值為+∞即可;
狀態轉移方程:f[i][V]=max{f[i-1][V],f[i-1][V-k*v[i]]+k*w[i]},其中0<=k*v[i]<=V
★ Max Sum Plus Plus http://acm.hdu.edu.cn/showproblem.php?pid=1024
1. 對於前n個數, 以v[n]為底取m段:
當n==m時,Sum[m][n]=Sum[m-1][n-1]+v[n],第n個數獨立成段;
當n>m時, Sum[m][n]=max{Sum[m-1][k],Sum[m][n-1]}+v[n]; 其中,m-1<=k<j,解釋為,v[n]要麼加在Sum[m][n-1],段數不變,要麼獨立成段接在前n-1個數取m-1段所能構成的最大值後面
2. 空間的優化:
通過狀態方程可以看出,取m段時,只與取m-1段有關,所以用滾動陣列來節省空間
FatMouse’s Speed http://acm.hdu.edu.cn/showproblem.php?pid=1160
要求:體重嚴格遞增,速度嚴格遞減,原始順序不定
按體重或者速度排序,即順數固定後轉化為最長上升子序列問題
Dp[i]表示為以第i項為底構成的最長子序列,Dp[i]=max(dp[j])+1,其中0<=j<i , w[i]>w[j]&&s[i]<s[j] 用一個index陣列構造最優解:記錄每一項接在哪一項後面,最後用max找出最大的dp[0…n],dex記錄下標,回溯輸出即可
Cstructing Roads http://acm.hdu.edu.cn/showproblem.php?pid=1025
以p或者r按升序排列以後,問題轉化為最長上升子序列
題目資料量比較大,只能採取二分查詢,n*log(n)的演算法
用一個數組記錄dp[]記錄最長的子序列,len表示長度,如果a[i]>dp[len], 則接在後面,len++; 否則在dp[]中找到最大的j,滿足dp[j]<a[i],把a[i]接在dp[j]後面;
FatMouse Chees http://acm.hdu.edu.cn/showproblem.php?pid=1078
Dp思想,用記憶化搜尋;簡單題,處理好邊界;
To the Max http://acm.hdu.edu.cn/showproblem.php?pid=1081
最大子矩陣
把多維轉化為一維的最大連續子序列;(HDU1003)
龜兔賽跑http://acm.hdu.edu.cn/showproblem.php?pid=2059
未總結
★ Employment Planning http://acm.hdu.edu.cn/showproblem.php?pid=1158
狀態表示: Dp[i][j]為前i個月的留j個人的最優解;Num[i]<=j<=Max{Num[i]};
j>Max{Num[i]}之後無意義,無謂的浪費 記Max_n=Max{Num[i]};
Dp[i-1]中的每一項都可能影響到Dp[i],即使Num[i-1]<<Num[i]
所以利用Dp[i-1]中的所有項去求Dp[i];
對於Num[i]<=k<=Max_n, 當k<j時, 招聘;
當k>j時, 解僱 然後求出最小值
Dp[i][j]=min{Dp[i-1][k…Max_n]+(招聘,解僱,工資);
Dividing http://acm.hdu.edu.cn/showproblem.php?pid=1059
一維Dp Sum為偶數的時候判斷Dp[sum/2]可不可達
Human Gene Factions http://acm.hdu.edu.cn/showproblem.php?pid=1080
狀態轉移方程:
f[i][j]=Max(f[i-1][j-1]+r[a[i]][b[j]], f[i][j-1]+r[‘-‘][b[j]],f[i-1][j]+r[a[i]][‘-‘]);
★ Doing Homework http://acm.hdu.edu.cn/showproblem.php?pid=1074
這題用到位壓縮;
那麼任務所有的狀態有2^n-1種
狀態方程為:Dp[next]=min{Dp[k]+i的罰時} 其中,next=k+(1<<i),k要取完滿足條件的值 k>>i的奇偶性決定狀態k
具體實現為: 對每種狀態遍歷n項任務,如果第i項沒有完成,則計算出Dp[next]的最優解
Free DIY Tour http://acm.hdu.edu.cn/showproblem.php?pid=1224
簡單的數塔Dp,考察的是細節的處理;
Dp[i]=Max{Dp[j]}+v[i] 其中j->i為通路;
v[n+1]有沒有初始化,Dp陣列有沒有初始化
這題不能用想當然的”最長路”來解決,這好像是個NP問題 解決不了的
重溫世界盃http://acm.hdu.edu.cn/showproblem.php?pid=1422
這題的狀態不難理解,狀態表示為,如果上一個城市剩下的錢不為負,也就是沒有被趕回杭電,則再考慮它對下一個城市的影響;如果上一個城市剩下的前加上當前城市的前大於當前城市的生活費,那麼Dp[i]=Dp[i-1]+1;
值得注意的而是這題的資料為100000;不可能以每個城市為起點來一次Dp,時間複雜度為n^2;足已超時;
我是這樣處理的,在儲存的資料後面再接上1…n的資料,這樣掃描一遍的複雜度為n;再加一個優化,當Dp[i]==n時,也就是能全部游完所有城市的時候,直接break;
Pearls http://acm.hdu.edu.cn/showproblem.php?pid=1300
Dp[i]=min{Dp[j]+V}, 0<=j<i, V為第j+1類珠寶到第i類全部以i類買入的價值;
Zipper http://acm.hdu.edu.cn/showproblem.php?pid=1501
Dp[i][j]=
★Fast Food http://acm.hdu.edu.cn/showproblem.php?pid=1227
這裡需要一個常識:在i到j取一點使它到區間每一點的距離之和最小,這一點為(i+j)/2用圖形即可證明;
Dp[i][j]=max{Dp[i-1][k]+cost[k+1][j] 其中,(i-1)<=k<j狀態為前j個position建i個depots
Warcraft http://acm.hdu.edu.cn/showproblem.php?pid=3008
比賽的時候這道DP卡到我網路中心停電!!! 臥槽~
因為你沒有回血效應,所以你掛掉的時間是一定的;
用Dp[i][j]表示第i秒剩餘j個單位的MP時怪物所剩的血量; 注意必須是剩餘,也就是說,初始化的時候,DP[0][100]=100; 其他Dp[0]狀態都不合法,因為沒有開戰的時候你的MP是滿的
狀態轉移方程為:
Dp[i+1][j-sk[k].mp+x]=min(Dp[i+1][j-sk[k].mp+x],Dp[i][j]+sk[k].at; 釋放第K種技能,物理攻擊可以看成是at=1,mp=0 的魔法;
Regular Words http://acm.hdu.edu.cn/showproblem.php?pid=1502
F[a][b][c]=F[a-1][b][c]+F[a][b-1][c]+F[a][b][c-1];
a>=b>=c;
Advanced Fruits http://acm.hdu.edu.cn/showproblem.php?pid=1503
最長公共子序列的加強版
# re: HDU 動態規劃(46道題目)傾情奉獻~ 【只提供思路與狀態轉移方程】 2011-06-23 18:45 | quality directory submission
To make money in the web, your product pages need to be detected among top results for specialized keys and goods. To realize that, you require the most experienced cheap directory submission service and optimization stuff. Professionals are able to turn visitors into clients.
HDU 動態規劃(46道題目)
原作者網址:http://www.cppblog.com/doer-xee/archive/2010/01/28/102629.html#Post
先標記 以後慢慢學習。
Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955
揹包;第一次做的時候把概率當做揹包(放大100000倍化為整數):在此範圍內最多能搶多少錢 最腦殘的是把總的概率以為是搶N家銀行的概率之和… 把狀態轉移方程寫成了f[j]=max{f[j],f[j-q[i].v]+q[i].money}(f[j]表示在概率j之下能搶的大洋);
正確的方程是:f[j]=max(f[j],f[j-q[i].money]*q[i].v) 其中,f[j]表示搶j塊大洋的最大的逃脫概率,條件是f[j-q[i].money]可達,也就是之前搶劫過;
始化為:f[0]=1,其餘初始化為-1 (搶0塊大洋肯定不被抓嘛)
最大報銷額 http://acm.hdu.edu.cn/showproblem.php?pid=1864
又一個揹包問題,對於每張發票,要麼報銷,要麼不報銷,0-1揹包,張數即為揹包;
轉移方程:f[j]=max(f[j],f[j-1]+v[i]);
噁心地方:有這樣的輸入資料 3 A:100 A:200 A:300
最大連續子序列 http://acm.hdu.edu.cn/showproblem.php?pid=1231
狀態方程:sum[i]=max(sum[i-1]+a[i],a[i]);最後從頭到尾掃一邊
也可以寫成:
Max=a[0];
Current=0;
for(i=0;i<n;i++)
{
if(Current<0)
Current=a[i];
else
Current+=a[i];
if(Current>Max)
Max=Current;
}
max sum http://acm.hdu.edu.cn/showproblem.php?pid=1003
同上,最大連續子序列
Largest Rectangle http://acm.hdu.edu.cn/showproblem.php?pid=1506
對於每一塊木板,Area=height[i]*(j-k+1) 其中,j<=x<=k,height[x]>=height[i];找j,k成為關鍵,一般方法肯定超時,利用動態規劃,如果它左邊高度大於等於它本身,那麼它左邊的左邊界一定滿足這個性質,再從這個邊界的左邊迭代下去
for(i=1;i<=n;i++)
{
while(a[l[i]-1]>=a[i])
l[i]=l[l[i]-1];
}
for(i=n;i>=1;i--)
{
while(a[r[i]+1]>=a[i])
r[i]=r[r[i]+1];
}
City Game http://acm.hdu.edu.cn/showproblem.php?pid=1505
1506的加強版,把2維轉換化成以每一行底,組成的最大面積;(注意處理連續與間斷的情況);
Bone Collector http://acm.hdu.edu.cn/showproblem.php?pid=2602
簡單0-1揹包,狀態方程:f[j]=max(f[j],f[j-v[i]]+w[i])
Super Jumping http://acm.hdu.edu.cn/showproblem.php?pid=1087
最大遞增子段和,狀態方程:sum[j]=max{sum[i]}+a[j]; 其中,0<=i<=j,a[i]<a[j]
命運http://acm.hdu.edu.cn/showproblem.php?pid=2571
狀態方程:sum[i][j]=max{sum[i-1][j],sum[i][k]}+v[i][j];其中1<=k<=j-1,且k是j的因子
Monkey And Banana http://acm.hdu.edu.cn/showproblem.php?pid=1069
狀態方程:f[j]=max{f[i]}+v[j];其中,0<=i<=j,w[i]<w[j],h[i]<h[j]
Big Event in HDU http://acm.hdu.edu.cn/showproblem.php?pid=1171
一維揹包,逐個考慮每個物品帶來的影響,對於第i個物品:if(f[j-v[i]]==0) f[j]=0;
其中,j為逆序迴圈,且j>=v[i]
數塔http://acm.hdu.edu.cn/showproblem.php?pid=2084
自底向上:dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+v[i][j];
免費餡餅http://acm.hdu.edu.cn/showproblem.php?pid=1176
簡單數塔
自底向上計算:dp[i][j]=max(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1])+v[i][j];處理邊界
I Need A Offer http://acm.hdu.edu.cn/showproblem.php?pid=1203
簡單0-1揹包,題目要求的是至少收到一份Offer的最大概率,我們得到得不到的最小概率即可,狀態轉移方程:f[j]=min(f[j],f[j-v[i]]*w[i]);其中,w[i]表示得不到的概率,(1-f[j])為花費j元得到Offer的最大概率
FATE http://acm.hdu.edu.cn/showproblem.php?pid=2159
二維完全揹包,第二層跟第三層的要順序迴圈;(0-1揹包逆序迴圈);狀態可理解為,在揹包屬性為 {m(忍耐度), s(殺怪個數)} 裡最多能得到的經驗值,之前的揹包犧牲體積,這個揹包犧牲忍耐度跟個數
注意: 最後掃的時候 外層迴圈為忍耐度,內層迴圈為殺怪個數,因為題目要求出剩餘忍耐度最大,沒有約束殺怪個數,一旦找到經驗加滿的即為最優解;
狀態轉移方程為: f[j][k]=max(f[j][k],f[j-v[i]][k-1]+w[i]); w[i]表示殺死第i個怪所得的經驗值,v[i]表示消耗的忍耐度
How To Type http://acm.hdu.edu.cn/showproblem.php?pid=2577
用兩個a,b陣列分別記錄Caps Lock開與關時列印第i個字母的最少操作步驟;
而對於第i個字母的大小寫還要分開討論:
Ch[i]為小寫: a[i]=min(a[i-1]+1,b[i-1]+2);不開燈直接字母,開燈則先關燈再按字母,最後保持不開燈; b[i]=min(a[i-1]+2,b[i-1]+2);不開燈則先按字母再開燈,開燈則Shift+字母(比關燈,按字母再開燈節省步數),最後保持開燈;
Ch[i]為大寫: a[i]=min(a[i-1]+2,b[i-1]+2); b[i]=min(a[i-1]+2,b[i-1]+1)
最後,b[len-1]++,關燈嘛O(∩_∩)O~
Coins http://acm.hdu.edu.cn/showproblem.php?pid=2844
類似於HDU1171 Big Event In HDU,一維DP,可達可不達
Beans http://acm.hdu.edu.cn/showproblem.php?pid=2845
橫豎分別求一下不連續的最大子段和;
狀態方程: Sum[i]=max(sum[j])+a[i];其中,0<=j<i-1;
Largest Submatrix http://acm.hdu.edu.cn/showproblem.php?pid=2870
列舉a,b,c 最大完全子矩陣,類似於HDU1505 1506
Matrix Swapping II http://acm.hdu.edu.cn/showproblem.php?pid=2830
最大完全子矩陣,以第i行為底,可以構成的最大矩陣,因為該題可以任意移動列,所以只要大於等於height[i]的都可以移動到一起,求出height>=height[i]的個數即可,這裡用hash+滾動,先求出height[i]出現的次數,然後逆序掃一遍hash[i]+=hash[i+1];
最少攔截系統http://acm.hdu.edu.cn/showproblem.php?pid=1257
兩種做法,一是貪心,從後往前貪;二是DP;
if(v[i]>max{dp[j]}) (0<=j<len)
dp[len++]=v[i];
Common Subsequence http://acm.hdu.edu.cn/showproblem.php?pid=1159
經典DP,最長公共子序列
Len[i][j]={len[i-1][j-1]+1,(a[i]==b[j]); max(len[i-1][j],len[i][j-1])}
初始化的優化:
for(i=0;i<a;i++)
for(j=0;j<b;j++)
len[i][j]=0;
for(i=1;i<=a;i++)
for(j=1;j<=b;j++)
if(ch1[i-1]==ch2[j-1])
len[i][j]=len[i-1][j-1]+1;
else
len[i][j]=max(len[i-1][j],len[i][j-1]);
★ 搬寢室http://acm.hdu.edu.cn/showproblem.php?pid=1421
狀態Dp[i][j]為前i件物品選j對的最優解
當i=j*2時,只有一種選擇即 Dp[i-2][j-1]+(w[i]-w[i-1])^2
當i>j*2時,Dp[i][j] = min(Dp[i-1][j],Dp[i-2][j-1]+(w[j]-w[j-1])^2)
★ Humble Numbers http://acm.hdu.edu.cn/showproblem.php?pid=1058
如果一個數是Humble Number,那麼它的2倍,3倍,5倍,7倍仍然是Humble Number
定義F[i]為第i個Humble Number
F[n]=min(2*f[i],3*f[j],5*f[k],7*f[L]), i,j,k,L在被選擇後相互移動
(通過此題理解到陣列有序特性)
★ Doing Homework Again http://acm.hdu.edu.cn/showproblem.php?pid=1789
這題為貪心,經典題;
切題角度,對於每個任務要麼在截至日期前完成要麼被扣分;所以考慮每個人物的完成情況即可;由於每天只能完成一個任務,所以優先考慮分值較大的任務,看看該任務能不能完成,只要能完成,即使提前完成,佔了其他任務的完成日期也沒關係,因為當前任務的分值最大嘛,而對於能完成的任務能拖多久就拖多久,以便騰出更多時間完成其他任務;
How Many Ways http://acm.hdu.edu.cn/showproblem.php?pid=1978
兩種D法,一是對於當前的點,那些點可達;二是當前點可達那些點;
明顯第二種方法高,因為第一種方法有一些沒必要的嘗試;
Dp[i][j]+=Dp[ii][jj]; (map[ii][jj]>=兩點的曼哈頓距離)
值得優化的地方,每兩點的曼哈頓距離可能不止求一次,所以預處理一下直接讀取
珍惜現在 感恩生活http://acm.hdu.edu.cn/showproblem.php?pid=2191
每個物品最多可取n件,多重揹包;
利用二進位制思想,把每種物品轉化為幾件物品,然後就成為了0-1揹包
Piggy-Bank http://acm.hdu.edu.cn/showproblem.php?pid=1114
完全揹包;常規揹包是求最大值,這題求最小值;
只需要修改一下初始化,f[0]=0,其他賦值為+∞即可;
狀態轉移方程:f[i][V]=max{f[i-1][V],f[i-1][V-k*v[i]]+k*w[i]},其中0<=k*v[i]<=V
★ Max Sum Plus Plus http://acm.hdu.edu.cn/showproblem.php?pid=1024
1. 對於前n個數, 以v[n]為底取m段:
當n==m時,Sum[m][n]=Sum[m-1][n-1]+v[n],第n個數獨立成段;
當n>m時, Sum[m][n]=max{Sum[m-1][k],Sum[m][n-1]}+v[n]; 其中,m-1<=k<j,解釋為,v[n]要麼加在Sum[m][n-1],段數不變,要麼獨立成段接在前n-1個數取m-1段所能構成的最大值後面
2. 空間的優化:
通過狀態方程可以看出,取m段時,只與取m-1段有關,所以用滾動陣列來節省空間
FatMouse’s Speed http://acm.hdu.edu.cn/showproblem.php?pid=1160
要求:體重嚴格遞增,速度嚴格遞減,原始順序不定
按體重或者速度排序,即順數固定後轉化為最長上升子序列問題
Dp[i]表示為以第i項為底構成的最長子序列,Dp[i]=max(dp[j])+1,其中0<=j<i , w[i]>w[j]&&s[i]<s[j] 用一個index陣列構造最優解:記錄每一項接在哪一項後面,最後用max找出最大的dp[0…n],dex記錄下標,回溯輸出即可
Cstructing Roads http://acm.hdu.edu.cn/showproblem.php?pid=1025
以p或者r按升序排列以後,問題轉化為最長上升子序列
題目資料量比較大,只能採取二分查詢,n*log(n)的演算法
用一個數組記錄dp[]記錄最長的子序列,len表示長度,如果a[i]>dp[len], 則接在後面,len++; 否則在dp[]中找到最大的j,滿足dp[j]<a[i],把a[i]接在dp[j]後面;
FatMouse Chees http://acm.hdu.edu.cn/showproblem.php?pid=1078
Dp思想,用記憶化搜尋;簡單題,處理好邊界;
To the Max http://acm.hdu.edu.cn/showproblem.php?pid=1081
最大子矩陣
把多維轉化為一維的最大連續子序列;(HDU1003)
龜兔賽跑http://acm.hdu.edu.cn/showproblem.php?pid=2059
未總結
★ Employment Planning http://acm.hdu.edu.cn/showproblem.php?pid=1158
狀態表示: Dp[i][j]為前i個月的留j個人的最優解;Num[i]<=j<=Max{Num[i]};
j>Max{Num[i]}之後無意義,無謂的浪費 記Max_n=Max{Num[i]};
Dp[i-1]中的每一項都可能影響到Dp[i],即使Num[i-1]<<Num[i]
所以利用Dp[i-1]中的所有項去求Dp[i];
對於Num[i]<=k<=Max_n, 當k<j時, 招聘;
當k>j時, 解僱 然後求出最小值
Dp[i][j]=min{Dp[i-1][k…Max_n]+(招聘,解僱,工資);
Dividing http://acm.hdu.edu.cn/showproblem.php?pid=1059
一維Dp Sum為偶數的時候判斷Dp[sum/2]可不可達
Human Gene Factions http://acm.hdu.edu.cn/showproblem.php?pid=1080
狀態轉移方程:
f[i][j]=Max(f[i-1][j-1]+r[a[i]][b[j]], f[i][j-1]+r[‘-‘][b[j]],f[i-1][j]+r[a[i]][‘-‘]);
★ Doing Homework http://acm.hdu.edu.cn/showproblem.php?pid=1074
這題用到位壓縮;
那麼任務所有的狀態有2^n-1種
狀態方程為:Dp[next]=min{Dp[k]+i的罰時} 其中,next=k+(1<<i),k要取完滿足條件的值 k>>i的奇偶性決定狀態k
具體實現為: 對每種狀態遍歷n項任務,如果第i項沒有完成,則計算出Dp[next]的最優解
Free DIY Tour http://acm.hdu.edu.cn/showproblem.php?pid=1224
簡單的數塔Dp,考察的是細節的處理;
Dp[i]=Max{Dp[j]}+v[i] 其中j->i為通路;
v[n+1]有沒有初始化,Dp陣列有沒有初始化
這題不能用想當然的”最長路”來解決,這好像是個NP問題 解決不了的
重溫世界盃http://acm.hdu.edu.cn/showproblem.php?pid=1422
這題的狀態不難理解,狀態表示為,如果上一個城市剩下的錢不為負,也就是沒有被趕回杭電,則再考慮它對下一個城市的影響;如果上一個城市剩下的前加上當前城市的前大於當前城市的生活費,那麼Dp[i]=Dp[i-1]+1;
值得注意的而是這題的資料為100000;不可能以每個城市為起點來一次Dp,時間複雜度為n^2;足已超時;
我是這樣處理的,在儲存的資料後面再接上1…n的資料,這樣掃描一遍的複雜度為n;再加一個優化,當Dp[i]==n時,也就是能全部游完所有城市的時候,直接break;
Pearls http://acm.hdu.edu.cn/showproblem.php?pid=1300
Dp[i]=min{Dp[j]+V}, 0<=j<i, V為第j+1類珠寶到第i類全部以i類買入的價值;
Zipper http://acm.hdu.edu.cn/showproblem.php?pid=1501
Dp[i][j]=
★Fast Food http://acm.hdu.edu.cn/showproblem.php?pid=1227
這裡需要一個常識:在i到j取一點使它到區間每一點的距離之和最小,這一點為(i+j)/2用圖形即可證明;
Dp[i][j]=max{Dp[i-1][k]+cost[k+1][j] 其中,(i-1)<=k<j狀態為前j個position建i個depots
Warcraft http://acm.hdu.edu.cn/showproblem.php?pid=3008
比賽的時候這道DP卡到我網路中心停電!!! 臥槽~
因為你沒有回血效應,所以你掛掉的時間是一定的;
用Dp[i][j]表示第i秒剩餘j個單位的MP時怪物所剩的血量; 注意必須是剩餘,也就是說,初始化的時候,DP[0][100]=100; 其他Dp[0]狀態都不合法,因為沒有開戰的時候你的MP是滿的
狀態轉移方程為:
Dp[i+1][j-sk[k].mp+x]=min(Dp[i+1][j-sk[k].mp+x],Dp[i][j]+sk[k].at; 釋放第K種技能,物理攻擊可以看成是at=1,mp=0 的魔法;
Regular Words http://acm.hdu.edu.cn/showproblem.php?pid=1502
F[a][b][c]=F[a-1][b][c]+F[a][b-1][c]+F[a][b][c-1];
a>=b>=c;
Advanced Fruits http://acm.hdu.edu.cn/showproblem.php?pid=1503
最長公共子序列的加強版