久久99精品久久久久久琪琪,久久人人爽人人爽人人片亞洲,熟妇人妻无码中文字幕,亚洲精品无码久久久久久久

動(dòng)態(tài)規(guī)劃總結(jié)經(jīng)典題目(經(jīng)典中的經(jīng)典)

時(shí)間:2019-05-13 19:24:41下載本文作者:會(huì)員上傳
簡(jiǎn)介:寫寫幫文庫(kù)小編為你整理了多篇相關(guān)的《動(dòng)態(tài)規(guī)劃總結(jié)經(jīng)典題目(經(jīng)典中的經(jīng)典)》,但愿對(duì)你工作學(xué)習(xí)有幫助,當(dāng)然你在寫寫幫文庫(kù)還可以找到更多《動(dòng)態(tài)規(guī)劃總結(jié)經(jīng)典題目(經(jīng)典中的經(jīng)典)》。

第一篇:動(dòng)態(tài)規(guī)劃總結(jié)經(jīng)典題目(經(jīng)典中的經(jīng)典)

動(dòng)態(tài)規(guī)劃總結(jié)——經(jīng)典問題總結(jié)

本文著重討論狀態(tài)是如何表示,以及方程是怎樣表示的。當(dāng)然,還附上關(guān)鍵的,有可能作為模板的代碼段。但有的代碼的實(shí)現(xiàn)是優(yōu)化版的。

經(jīng)典問題總結(jié)

最長(zhǎng)上升子序列(LIS)

問題描述如下:

設(shè)L=是n個(gè)不同的實(shí)數(shù)的序列,L的遞增子序列是這樣一個(gè)子序列Lin=,其中k1 a[n] 則存在長(zhǎng)度為1的不下降子序列a[n-1]或者a[n]。

有了以上的思想,DP方程就呼之欲出了(這里是順序推的,不是逆序的): DP[I]=MAX(1,DP[J]+1)J=0,1,...,I-1

但這樣的想法實(shí)現(xiàn)起來是)O(n^2)的。本題還有更好的解法,就是O(n*logn)。利用了長(zhǎng)升子序列的性質(zhì)來優(yōu)化,以下是優(yōu)化版的代碼:

//最長(zhǎng)不降子序 const int SIZE=500001;int data[SIZE];int dp[SIZE];

//返回值是最長(zhǎng)不降子序列的最大長(zhǎng)度,復(fù)雜度O(N*logN)

int LCS(int n){ //N是DATA數(shù)組的長(zhǎng)度,下標(biāo)從1開始 int len(1),low,high,mid,i;

dp[1]=data[1];for(i=1;i<=n;++i){ low=1;high=len;

while(low<=high){ //二分 mid=(low+high)/2;if(data[i]>dp[mid]){ low=mid+1;} else {

high=mid-1;} }

dp[low]=data[i];if(low>len){ ++len;} }

return len;}

最長(zhǎng)公共子序列(LCS)

給出兩個(gè)字符串a(chǎn), b,求它們的最長(zhǎng)、連續(xù)的公共字串。

這很容易就想到以DP[I][J]表示A串匹配到I,B串匹配到J時(shí)的最大長(zhǎng)度。則:

0 I==0 || J==0

DP[I][J]=DP[I-1][J-1]+ 1 A[I]==B[J] MAX(DP[I-1][J],DP[I][J-1])不是以上情況

但這樣實(shí)現(xiàn)起來的空間復(fù)雜度為O(n^2),而上面的方程只與第I-1行有關(guān),所以可以用兩個(gè)一維數(shù)組來代替。以下是代碼:

//最長(zhǎng)公共子序列

const int SIZE=1001;

int dp[2][SIZE];//兩個(gè)一維數(shù)組

//輸入兩個(gè)字符串,返回最大的長(zhǎng)度

int LCS(const string& a,const string& b){ int i,j,flag;

memset(dp,0,sizeof(dp));

flag=1;

for(i=1;i<=a.size();++i){ for(j=1;j<=b.size();++j){

if(a[i-1]==b[j-1])dp[flag][j]=dp[1-flag][j-1]+1;else dp[flag][j]=MAX(dp[flag][j-1],dp[1-flag][j]);}

flag=1-flag;}

return dp[1-flag][b.size()];}

01背包

有N件物品和一個(gè)容量為V的背包。第i件物品的大小是c[i],價(jià)值是w[i]。求解將哪些物品裝入背包可使價(jià)值總和最大。

用DP[I][J] 表示前I件物品放入一個(gè)容量為J的背包可以獲得的最大價(jià)值。則 DP[I][J]= DP[I-1][J] ,J

MAX(DP[I-1][J],DP[I-1][J-C[I]]+W[I]), J>=C[I]

這樣實(shí)現(xiàn)的空間復(fù)雜度為O(VN),實(shí)際上可以優(yōu)化到O(V)。以下是代碼: const int MAXW=13000;//最大重量 const int MAXN=3450;//最大物品數(shù)量

int c[MAXN];//物品的存放要從下標(biāo)1開始 int w[MAXN];//物品的存放要從下標(biāo)1開始 int dp[MAXW];

//不需要將背包裝滿,則將DP數(shù)組全部初始化為0

//要將背包裝滿,則初始化為DP[0]=0,DP[1]…DP[V]=-1(即非法狀態(tài))int Packet(int n,int v){ int i,j;

memset(dp,0,sizeof(dp));for(i=1;i<=n;++i){

for(j=v;j>=c[i];--j){ //這里是倒序,別弄錯(cuò)了 dp[j]=MAX(dp[j],dp[j-c[i]]+w[i]);} }

return dp[v];}

完全背包問題

有N種物品和一個(gè)容量為V的背包,每種物品都有無限件可用。第i種物品的費(fèi)用是c[i],價(jià)值是w[i]。求解將哪些物品裝入背包可使這些物品的費(fèi)用總和不超過背包容量,且價(jià)值總和最大。

很容易可以得到這種狀態(tài)表示:用DP[I][J] 表示前I件物品放入一個(gè)容量為J的背包可以獲得的最大價(jià)值。則

DP[I][J]=MAX(DP[I-1][J],DP[I-1][J-K*C[I]]+K*W[I])0<=K*C[I]<=J 這樣的復(fù)雜度是O(V*Σ(V/c[i]))

有更好的做法,那就是利用01背包的優(yōu)化原理。在優(yōu)化的代碼中,之所以第二重循環(huán)是倒序,是為了防止重復(fù)拿,那么只要將其變?yōu)轫樞蚣纯梢灾貜?fù)取。代碼就不給了。

多重背包問題

有N種物品和一個(gè)容量為V的背包。第i種物品最多有n[i]件可用,每件費(fèi)用是c[i],價(jià)值是w[i]。求解將哪些物品裝入背包可使這些物品的費(fèi)用總和不超過背包容量,且價(jià)值總和最大。

這題仍然可以用到上一題的思想,DP表示狀態(tài)與上面的相同。方程為: DP[I][J]=MAX(DP[I-1][J],DP[I-1][J-K*C[I]]+K*W[I])

不同的是K的范圍,0<=K<=N[I] && 0<=K*C[I]<=J 這樣的復(fù)雜度為O(V*Σn[i])。有更好的想法就是先用二進(jìn)制來劃分。將第i種物品分成若干件物品,其中每件物品有一個(gè)系數(shù),這件物品的費(fèi)用和價(jià)值均是原來的費(fèi)用和價(jià)值乘以這個(gè)系數(shù)。使這些系數(shù)分別為1,2,4,...,2^(k-1),n[i]-2^k+1,且k是滿足n[i]-2^k+1>0的最大整數(shù)。然后用01背包做,這樣的復(fù)雜度為O(V*Σlog n[i])。關(guān)鍵代碼: const int SIZE=1001;int dp[SIZE];

int num[SIZE],c[SIZE],w[SIZE];//num[i]是I物品的件數(shù),C[I]是費(fèi)用,W[I]是價(jià)值 int MultiPack(int n,int v){ //存入?yún)?shù),N是物品種類數(shù),V是背包容量 int i,j,k;

memset(dp,0,sizeof(dp));

for(i=1;i<=n;++i){ //存放物品的數(shù)組下標(biāo)從1開始 if(c[i]*num[i]>=v){ for(j=c[i];j<=v;++j){

dp[j]=MAX(dp[j],dp[j-c[i]]+w[i]);} }

else { //使用二進(jìn)制劃分 k=1;

while(k=k*c[i];--j){

dp[j]=MAX(dp[j],dp[j-k*c[i]]+k*w[i]);} num[i]-=k;k*=2;}

for(j=v;j>=num[i]*c[i];--j){

dp[j]=MAX(dp[j],dp[j-num[i]*c[i]]+num[i]*w[i]);} } }

return dp[v];}

狀態(tài)表示總結(jié) 一維的狀態(tài)表示

DP的表示形式通常為:DP[I]表示取到第I個(gè)/種物品時(shí)的最優(yōu)值。DP方程的形式:DP[I]=MAX(DP[I],DP[J]+P[I])其中0<=J

有一些題可能要將一些額外的東西也認(rèn)為是物品。如HDU2059龜兔賽跑這題,需要將開始點(diǎn)和終點(diǎn)也認(rèn)為是加油站,然后才以DP[I]表示到第I個(gè)加油站并加滿油的最短時(shí)間。

有一些題可以將看似二維的情況轉(zhuǎn)化為一維的情況來做。如HDU 1081這題。大意是給出一個(gè)含有正數(shù)和負(fù)數(shù)的N階矩陣,求一個(gè)子矩陣使得子矩陣內(nèi)所有數(shù)的和最大。這樣的題可以將幾行合并為一行做。即枚舉就將第I行到第J行合并為一行,然后再用DP[K]=MAX(DP[K-1],0)+ARR[K],K是表示第K列。

有一些題是DP與暴力相結(jié)合,如POJ 3267 The Cow Lexicon這題。大意是給出一個(gè)長(zhǎng)的字符串,還有若干個(gè)短的字符串,問長(zhǎng)字符中至少要?jiǎng)h除幾個(gè)字符才能使得長(zhǎng)字符串中的子字符串都與某個(gè)短字符串相對(duì)應(yīng)。dp[i]表示從I到LEN-1需要?jiǎng)h除的最少字符串?dāng)?shù),則dp[i]=min(dp[i+1]+1,dp[k]+del)其中dp[i+1]+1是沒有找到匹配的情況,dp[k]+del是有匹配的情況,K表示從I開始匹配,到匹配完后的最后一個(gè)字符的位置,DEL表示在匹配過程中要?jiǎng)h除的字符數(shù)。由于方程的特點(diǎn),要從最后一個(gè)字符向第一個(gè)字符推去。中間要?jiǎng)h除的字符數(shù)用暴力找出。

有一些題用DP來枚舉全部的范圍,如POJ 1925 Spiderman這題。用DP[I]表示到達(dá)這個(gè)位置的最小跳數(shù)。其中DP數(shù)組為dp[1000005],這是可能跳到的全部范圍。

二維狀態(tài)表示

通常是用來處理兩種事物。DP[I][J]通常表示A的前I個(gè)和B的前J個(gè)XX的最優(yōu)值。

DP方程之一:DP[I][J]=MAX(DP[I-1][J-1]+P[XX],DP[I][J-1]+P[YY],DP[I-1][J]+P[ZZ])這里的XX,YY,ZZ是表示某某狀態(tài)得到的結(jié)果。

DP方程之二:DP[I][J]=MAX(DP[I][J],DP[I-1][K]+P[I][J]),其中0<=K

對(duì)第三種DP方程舉個(gè)例:POJ 3280 Cheapest Palindrome這題。大意是給出一個(gè)字符串,你可在任意位置增加或刪除字符,每增加或刪除一個(gè)字符都有一個(gè)對(duì)應(yīng)的代價(jià),求將其變?yōu)榛匚拇淖钚〈鷥r(jià)。以dp[i][j]表示從i到j(luò)要變成回文字符串的最小代價(jià),則

dp[i][j] = min{ dp[i+1][j] + {去掉X的代價(jià)},dp[i+1][j] + {加上X的代價(jià)},dp[i][j-1]+ {去掉Y的代價(jià)},dp[i][j-1] +{加上Y的代價(jià)}}; 算DP[I][J]時(shí),要知道DP[I+1][J]的值,對(duì)于這類DP其實(shí)現(xiàn)方法如下所示:

for(t=1;t

有時(shí)可以將DP與HASH相結(jié)合。如:POJ 1054 The Troublesome Frog這題。大意是在一個(gè)坐標(biāo)系中給出N個(gè)點(diǎn),求找出以哪兩點(diǎn)作一條直線經(jīng)過的點(diǎn)數(shù)最多。以DP[I][J]表示過第J點(diǎn)和第I點(diǎn)的直線一共經(jīng)過的點(diǎn)數(shù)。DP[I][J]=(DP[J][INDEX]+1,-INF),先算出INDEX這點(diǎn)的坐標(biāo),然后用哈希查找,如果找到,則執(zhí)行DP[J][INDEX]+1,如果找不到則用-INF表示不存在。

對(duì)于整除類型的題,如果要用DP做,那么其中有一維通常是佘數(shù)。如:POJ 1745Divisibility這題,dp[i][j]表示對(duì)前I個(gè)數(shù)進(jìn)行了處理,余數(shù)為J的情況 帶偏移的狀態(tài)表示

DP的表示形式通常為:DP[I][J]表示到第I個(gè)XX時(shí),YY與ZZ之差為J時(shí)的最優(yōu)值。例如:POJ 1837這題。

題目大意:給出天平c個(gè)掛鉤的位置,然后給出g個(gè)物品的質(zhì)量,將物品掛在天平上,問使天平平衡的方法有幾種。

思想:用l[i]表示第i個(gè)點(diǎn)的x坐標(biāo)值,用w[i]表示第i個(gè)砝碼的重量,用dp[i][j]表示加了i個(gè)砝碼,兩邊力矩之差為j的可能方法數(shù),則本題只要計(jì)算出dp[i][0],即最終力矩差為0的方法數(shù)即可。由于質(zhì)量差可能為負(fù),這里加上一個(gè)偏移量,考慮原題的數(shù)據(jù)可知,要想平衡,則一邊力矩至多為15*25*10=3750,故每個(gè)j加上3750。狀態(tài)轉(zhuǎn)移方程:dp[i+1][k+w[i]*l[j]]+= dp[i][k],i=0~g,j=0~c,k=0~7500。輸出結(jié)果:dp[w][3750]

動(dòng)態(tài)規(guī)劃變態(tài)總結(jié)

by

zeus

1:Pku acm 1163 the Triangle

2:Pku acm 1953 World Cup Noise //說白了就是斐波那切數(shù)列

3:Pku acm 1458 Common Subsequence Lcs

4:Pku acm 2250 Compromise記錄路徑的lcs

5:Pku acm 1159 Palindrome 回文串

6:Pku acm 1080 Humman Gene Function

7:Pku acm 2192 Zipper 判斷2個(gè)字符串能否組成1個(gè)字符串

8:Pku acm 3356 AGTC 一個(gè)字符串到另一個(gè)的最小步驟

9:Pku acm 1887 Testing the CATCHER最長(zhǎng)下降子序列

10:Pku acm 2533 Longest Ordered Subsequence最長(zhǎng)上升子序列

11:Pku acm 1631 Bridging signals最長(zhǎng)上升子序列的加強(qiáng)版….二分法

12:Pku acm 1157 LITTLE SHOP OF FLOWERS

13:Pku acm 1088 滑雪

14:Pku 1050 To the Max

15:Pku 1050 To the Max最大線段和的加強(qiáng)板…..二維的

16:Pku 1014 dividing

17: Pku acm 1160 post office

18: pku acm 1015 Jury Compromise

19: hdoj 2546飯卡

20:pku 1837 Balance

21: pku 3267 The Cow Lexicon

22:Pku 1742 Coins

//走塔....經(jīng)典的dp #include “iostream” using namespace std;int max(int a,int b){

return a>b?a:b;} int main(){

int n,i,j;

int a[100][100];

int f[100];while(scanf(“%d”,&n)>0){

for(i=0;i

for(j=0;j<=i;j++)

{

scanf(“%d”,&a[i][j]);

if(i==n-1)

f[j]=a[i][j];

}

for(i=n-2;i>=0;i--)

{

for(j=0;j<=n-1;j++)

if(f[j]>f[j+1])

f[j]=f[j]+a[i][j];

else

f[j]=f[j+1]+a[i][j];

}

printf(“%dn”,f[0]);}

system(“pause”);}

2:Pku acm 1953 World Cup Noise //說白了就是斐波那切數(shù)列

#include “iostream” using namespace std;int main(){

int n,m;

int i;

int f[100];

f[0]=2;

f[1]=3;

scanf(“%d”,&n);

for(i=2;i<100;i++)

{

f[i]=f[i-1]+f[i-2];

}

for(i=0;i

{

scanf(“%d”,&m);

{

printf(“Scenario #%d:n%dnn”,i+1,f[m-1]);

}

} }

3:Pku acm 1458 Common Subsequence Lcs經(jīng)典 #include “iostream” #include “cstring” using namespace std;int setmax(int a,int b){

if(a>b)

return a;

else return b;} int f[8100][8100];main(){

char s1[800];

char s2[800];

int i,j;

int sl1,sl2;

while(scanf(“%s %s”,&s1,&s2)!=EOF)

{

sl1=strlen(s1);

sl2=strlen(s2);

for(i=0;i

{

f[0][i]=0;

f[i][0]=0;

}

for(i=1;i

for(j=1;j

{

if(s1[i-1]==s2[j-1])

f[i][j]=f[i-1][j-1]+1;

else

f[i][j]=setmax(f[i-1][j],f[i][j-1]);

} printf(“%dn”,f[i-1][j-1]);

} } 4:Pku acm 2250 Compromise記錄路徑的lcs #include “iostream” #include “string” using namespace std;#define N 100 struct node {

string s;}s1[N],s2[N];int f[N][N];int path[N][N];string temp;int flag;void lcs(int i,int j){

if(i==0||j==0)return;

if(path[i][j]==1){

lcs(i-1,j-1);

{

if(flag!=1){

cout<

flag=1;}

else

cout<

}

else

if(path[i][j]==2)lcs(i-1,j);

else lcs(i,j-1);} int main(){

int i=0,j;

int len1,len2;

while(cin>>s1[0].s)

{

memset(f,0,sizeof(f));

i=1;

while(1){

cin>>temp;

if(temp==“#”)break;

s1[i++].s=temp;

}

len1=i;

i=0;

while(1){

cin>>temp;

if(temp==“#”)break;

s2[i++].s=temp;

}

len2=i;

memset(path,0,sizeof(path));

for(i=0;i<=len1;i++)

for(j=0;j<=len2;j++)

if(i==j)f[i][j]=1;

for(i=1;i<=len1;i++)

for(j=1;j<=len2;j++)

{

if(s1[i-1].s==s2[j-1].s)

{

f[i][j]=f[i-1][j-1]+1;

path[i][j]=1;

}

else if(f[i-1][j]>=f[i][j-1])

{

f[i][j]=f[i-1][j];

path[i][j]=2;

}

else

{

f[i][j]=f[i][j-1];

path[i][j]=3;

}

}

flag=1;

lcs(len1,len2);

cout<

} }

5:Pku acm 1159 Palindrome 回文串

帶有些許優(yōu)化的lcs #include “iostream” #include “string” #include “algorithm” using namespace std;int a[5005],b[5005];int c[3],d[3];string s1,s2;int main(){

int m,n=0;

int i,j;

while(cin>>n)

{

if(n==0)break;

cin>>s1;

} }

s2=s1;reverse(s2.begin(),s2.end());

memset(a,0,sizeof(a));

memset(b,0,sizeof(b));for(i=0;i

{

b[0]=0;

for(j=0;j

{

if(s1[i]==s2[j])

{

b[j+1]=a[j]+1;

}

else

if(b[j]>a[j+1])

{

b[j+1]=b[j];

}

else if(b[j]

{

b[j+1]=a[j+1];

}

}

for(j=0;j<=n;j++)

a[j]=b[j];

}

printf(“%dn”,n-b[n]);14

6:Pku acm 1080 Humman Gene Function

#include “iostream” using namespace std;int f[250][250];int g[250][250];char s1[180];char s2[180];int maxnum(int x,int y,int z){

int zz= x>y?x:y;

return zz>z?zz:z;} void make(){

f[1][1]=5;f[1][2]=-1;f[1][3]=-2;f[1][4]=-1;f[1][5]=-3;

f[2][1]=-1;f[2][2]=5;f[2][3]=-3;f[2][4]=-2;f[2][5]=-4;

f[3][1]=-2;f[3][2]=-3;f[3][3]=5;f[3][4]=-2;f[3][5]=-2;

f[4][1]=-1;f[4][2]=-2;f[4][3]=-2;f[4][4]=5;f[4][5]=-1;

f[5][1]=-3;f[5][2]=-4;f[5][3]=-2;f[5][4]=-1;f[5][5]=-99999;} int sw(char ch){

if(ch=='A')

return 1;

else if(ch=='C')

return 2;

else if(ch=='G')

return 3;

else if(ch=='T')

return 4;

else if(ch=='-')

return 5;} int find(char ch1,char ch2){

return f[sw(ch1)][sw(ch2)];} int main(){

make();

int sl1,sl2,i,j,m;

memset(g,0,sizeof(0));

cin>>m;

while(m--)

{

cin>>sl1;

cin>>s1;

cin>>sl2;

cin>>s2;

for(i=1;i<=sl2;i++)

g[0][i] = g[0][i-1]+find('-',s2[i-1]);

for(i=1;i<=sl1;i++)

g[i][0] = g[i-1][0]+find(s1[i-1],'-');

for(i=1;i<=sl1;i++)

for(j=1;j<=sl2;j++)

{

g[i][j]=maxnum(g[i][j-1]+find('-',s2[j-1]),g[i-1][j]+find(s1[i-1],'-'),g[i-1][j-1]+find(s1[i-1],s2[j-1]));

}

cout<

7:Pku acm 2192 Zipper 判斷2個(gè)字符串能否組成1個(gè)字符串

//用動(dòng)態(tài)規(guī)劃解決,ok[i][j]表示str1長(zhǎng)度為i的前綴和str2長(zhǎng)度為j的后綴能否組成目標(biāo)中str中長(zhǎng)度為i+j的前綴串

#include “iostream” using namespace std;int i,j,n;int sl1,sl2,sl3;char s1[500],s2[500],s3[500];int f[500][500];int main(){

int count=0;

scanf(“%d”,&n);

while(n--)

{count++;

memset(f,0,sizeof(f));

scanf(“%s %s %s”,s1,s2,s3);

sl1=strlen(s1);

sl2=strlen(s2);

sl3=strlen(s3);

for(j=0;j

{

if(s1[j]==s3[j])

f[j+1][0]=1;

else

break;

}

for(i=0;i

{

if(s2[i]==s3[i])

f[0][i+1]=1;

else

break;

}

for(i=0;i<=sl1;i++)

for(j=0;j<=sl2;j++)

{

if(!(i==0&&j==0))

if(s1[i]==s3[i+j]&&f[i][j]==1)

f[i+1][j]=1;

if(s2[j]==s3[i+j]&&f[i][j]==1)

f[i][j+1]=1;

}

printf(“Data set %d: ”,count);

if(f[sl1][sl2]==1)

printf(“yesn”);

else

printf(“non”);

} }

8:Pku acm 3356 AGTC 一個(gè)字符串到另一個(gè)的最小步驟

#include “iostream” #include “string” using namespace std;int setmin(int x,int y,int z){

int xx=x>y?y:x;

return xx>z?z:xx;} string s1,s2;int f[1005][1005];int main(){

int n,m;

int i,j;

while(cin>>n)

{

cin>>s1;

cin>>m;

cin>>s2;

for(i=0;i<=n;i++)

f[i][0]=i;

for(i=0;i<=m;i++)

f[0][i]=i;

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

for(j=1;j<=m;j++)

{

if(s1[i-1]==s2[j-1])

f[i][j]=setmin(f[i-1][j]+1,f[i][j-1]+1,f[i-1][j-1]);

else

f[i][j]=setmin(f[i-1][j]+1,f[i][j-1]+1,f[i-1][j-1]+1);

}

cout<

} }

9:Pku acm 1887 Testing the CATCHER最長(zhǎng)下降子序列 #include “iostream” using namespace std;int a[32769],f[32769];int main(){

int i,j,n,max;

int count=0;

while(1)

{

count++;

scanf(“%d”,&a[0]);

if(a[0]==-1)break;

i=1;

while(1)

{

scanf(“%d”,&a[i]);

if(a[i]==-1)

break;

i++;

}

n=i;

max=0;

memset(f,0,sizeof(f));

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

{

f[i]=1;

for(j=0;j<=i;j++)

{

if(a[j-1]>a[i-1]&&f[j]+1>f[i])

f[i]=f[j]+1;

if(f[i]>max)

max=f[i];

}

}

printf(“Test #%d:n”,count);

printf(“ maximum possible interceptions: %dnn”,max);

} }

10:Pku acm 2533 Longest Ordered Subsequence最長(zhǎng)上升子序列

#include “iostream” using namespace std;int f[10000];int a[10000];int main(){

int n,i,j,max;

while(scanf(“%d”,&n)!=EOF)

{

for(i=0;i

{

scanf(“%d”,&a[i]);

}

memset(f,0,sizeof(f));

max=0;

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

{

f[i]=1;

for(j=0;j<=i;j++)

if(a[j-1]f[i])

f[i]=f[j]+1;

if(f[i]>max)

max=f[i];

}

printf(“%dn”,max);

} } 11:Pku acm 1631 Bridging signals最長(zhǎng)上升子序列的加強(qiáng)版….二分法

#include “iostream” #include “string” using namespace std;#define N 50000 int f[N];int a[N];int main(){

int n,m,i,j,max;

scanf(“%d”,&n);

while(n--)

{

max=-99;

memset(f,0,sizeof(f));

scanf(“%d”,&m);

for(i=0;i

{

scanf(“%d”,&a[i]);

// f[i]=a[i];

}

f[1]=a[0];

int s=1;

int l,r,mid;

for(i=1;i

{

if(f[s]

f[++s]=a[i];

else

{

l=0;

r=s;

mid=(l+r)>>1;

while(l<=r)

{

mid=(l+r)>>1;

f[mid]

}

f[l]=a[i];

}

}

printf(“%dn”,s);} }

12:Pku acm 1157 LITTLE SHOP OF FLOWERS

該題也是經(jīng)典的動(dòng)態(tài)規(guī)劃,題目敘述的依然很麻煩,其實(shí)簡(jiǎn)化一下就是這樣的:例如下面這個(gè)例子就是:3表示行,5表示列,然后在下面的3行5列每一行選一個(gè)數(shù),使這3個(gè)數(shù)最大,要求選的數(shù)列數(shù)必須依次增大,就是從左上方想右下方選3個(gè)數(shù)使和最大。3 5 7 23-5-24 16 5 21-4 10 23-21 5-4-20 20 #include “iostream” using namespace std;#define N 5000 int f[N][N];int w[N][N];int main(){

int n,m,i,j,k;while(cin>>n>>m){

for(i=0;i

for(j=0;j

cin>>w[i][j];

for(i=0;i

for(j=0;j

f[i][j]=-50000;

for(i=1;i

f[1][i]=w[0][i-1];

for(i=2;i<=n;i++)

{

for(j=1;j<=m;j++)

{

if(j>=i)

for(k=1;k

if(f[i][j]

f[i][j]=f[i-1][k]+w[i-1][j-1];

}

}

int max=-50000;

for(i=0;i<=m;i++)

if(f[n][i]>max)

max=f[n][i];

printf(“%dn”,max);} }

13:Pku acm 1088 滑雪 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9

一個(gè)人可以從某個(gè)點(diǎn)滑向上下左右相鄰四個(gè)點(diǎn)之一,當(dāng)且僅當(dāng)高度減小。在上面的例子中,一條可滑行的滑坡為24-17-16-1。當(dāng)然25-24-23-...-3-2-1更長(zhǎng)。事實(shí)上,這是最長(zhǎng)的一條。輸出最長(zhǎng)區(qū)域的長(zhǎng)度。

#include “iostream” using namespace std;int h[100][100];int f[100][100];int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};int r,c;bool judge(int x,int y){

if(x>=0&&y>=0&&x

return true;

else return false;} int dp(int i,int j){

int max=0,xi,yi,k;

if(f[i][j]!=0)

return f[i][j];

for(k=0;k<4;k++)

{

xi=i+dir[k][0];

yi=j+dir[k][1];

if(judge(xi,yi)&&h[i][j]>h[xi][yi])

{

int num=dp(xi,yi);

if(num>max)

max=num;

}

}

f[i][j]=max+1;

return max+1;} int main(){

int i,j;

int temp,max;

while(cin>>r>>c)

{

for(i=0;i

for(j=0;j

{

cin>>h[i][j];

}

memset(f,0,sizeof(f));

max=0;

for(i=0;i

{

for(j=0;j

{

temp=dp(i,j);

max=max>temp?max:temp;

}

}

cout<

} }

14:hdoj1003 max num #include “iostream” using namespace std;int f[100005];int a[100005];int main(){

int num,n,i,j;

int st,end,now,max;

int flag;

int count=0;

int k;cin>>num;

while(num--)

{

count++;

cin>>n;

for(i=0;i

cin>>a[i];

now=0;

max=-999;

k=1;

for(i=0;i

{

now+=a[i];

if(now>max)

{

max=now;

end=i+1;

st=k;

}

if(now<0)

{

now=0;

k=i+2;

}

}

printf(“Case %d:n”,count);

printf(“%d %d %dn”,max,st,end);

if(num!=0)printf(“n”);

}

return 0;

}

15:Pku 1050 To the Max最大線段和的加強(qiáng)板…..二維的 #include “iostream” using namespace std;int n,i,j,cnt,now,maxx,k;int a[150][150];int s[150][150][150];int main(){

while(scanf(“%d”,&n)!=EOF)

{

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

for(j=1;j<=n;j++)

{

scanf(“%d”,&a[i][j]);

s[i][i][j]=a[i][j];

}

for(i=1;i

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

for(k=1;k<=n;k++)

{

s[i][j][k]=s[i][j-1][k]+a[j][k];

}

maxx=0;

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

for(j=1;j<=n;j++)

{

cnt=0;

now=0;

for(k=1;k<=n;k++)

{

cnt+=s[i][j][k];

if(cnt>now)

now=cnt;

if(cnt<0)

cnt=0;

}

if(now>maxx)maxx=now;

}

printf(“%dn”,maxx);

}

return 0;}

16:Pku 1014 dividing

實(shí)在不會(huì)做先抄個(gè)代碼 #include

bool opt[60000];

int num=0;

int mid,max;

int stone[7];

int input()

{

scanf(“%d%d%d%d%d%d”,&stone[1],&stone[2],&stone[3],&stone[4],&stone[5],&stone[6]);

if(!stone[6]&&!stone[1]&&!stone[2]&&!stone[3]&&!stone[4]&&!stone[5]){return 1;} //讀到末行

num++;

printf(“Collection #%d:n”,num);

mid=0;

for(int i=1;i<=6;i++)mid+=stone[i]*i;

if(mid % 2 ==1)//明顯的剪枝

{

printf(“Can't be divided.nn”);

return 2;

}

else mid/=2;//我們的任務(wù)就是求opt

return 0;

}

void dp()

{

memset(opt,0,60000);//初始化,opt所有成員為false

opt[0]=true;//opt[0]顯然是true

max=0;//當(dāng)前最大值是0

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

{

if(stone[i]>0)

{

for(int j=max;j>=0;j--)

// 從當(dāng)前最大值開始往下算

if(opt[j])//找到可行的j

{

if(opt[mid])

//判斷是否已經(jīng)求出結(jié)果

{

printf(“Can be divided.nn”);

return;

}

for(int k=1;k<=stone[i];k++)//在剛找到的可行j基礎(chǔ)上加石頭.{

if(j+k*i>mid || opt[j+k*i])break;//如果已經(jīng)大于總價(jià)值的一半mid,或opt[j+k*i]已計(jì)算,跳出循環(huán)

opt[j+k*i]=true;

}

}

}

max=max+i*stone[i];//更新當(dāng)前最大值

if(max>mid)max=mid;

//如果當(dāng)前最大值超過了mid,對(duì)其賦值為mid

}

printf(“Can't be divided.nn”);//如果從1到6循環(huán)完一遍后仍然沒有算出opt[mid],說明無解

}

int main()

{

while(1)

{

int t=input();

switch(t)

{

case 1 : return 0;

//讀到末行,結(jié)束

case 2 : continue;//讀到明顯的剪枝

default : dp();

}

}

return 0;

}

17: Pku acm 1160 post office 貼代碼

題目給出m個(gè)村莊及其距離,給出n個(gè)郵局,要求怎么建n個(gè)郵局使代價(jià)最小。思路:用opt[i][j]記錄把前i個(gè)郵局建到前j個(gè)村莊中的最優(yōu)解,用cost[i][j]記錄所有在i到j(luò)村莊中,建1個(gè)郵局的最小代價(jià)。顯然郵局應(yīng)該設(shè)到中點(diǎn)。讓前i個(gè)郵局覆蓋前j個(gè)村莊,第i+1個(gè)郵局覆蓋第j+1至j+k個(gè)村莊(j+k<=n),則狀態(tài)轉(zhuǎn)移方程為 w[i+1][j+k]=min{w[i][j]+cost[j+1][j+k];}(k+j<=n)Cost數(shù)組存放從i到j(luò)中有一個(gè)郵局的最小代價(jià),顯然該郵局應(yīng)該放在中間

W[i][j] 表示前i個(gè)郵局覆蓋前j個(gè)村莊的最小代價(jià),對(duì)于i=1來說,w[i][j] = cost[i][j],讓前2個(gè)郵局覆蓋前j個(gè)村莊,也就是i=2的情況,可能是一下情況的最優(yōu)解:第一個(gè)郵局覆蓋第一個(gè)村莊,第二個(gè)村莊覆蓋2-j個(gè)村莊,或者第一個(gè)郵局覆蓋第1-2個(gè)村莊,第二個(gè)村莊覆蓋3-j個(gè)村莊,第一個(gè)郵局覆蓋第1-3個(gè)村莊,第二個(gè)村莊覆蓋4-j個(gè)村莊,等等等等

#include “iostream” using namespace std;int cost[310][310];int w[310][310];#define max 3000000 int main(){ int i,j,k,m,n,mid,q,v[310];while(scanf(“%d%d”,&m,&n)!=EOF){

for(i=1;i<=m;i++)

scanf(“%d”,&v[i]);

memset(cost,0,sizeof(cost));

for(i=1;i<=m;i++)

for(j=i;j<=m;j++)

{

mid=(i+j)/2;

for(k=i;k<=mid;k++)

cost[i][j]=cost[i][j]+v[mid]-v[k];

for(k=mid+1;k<=j;k++)

cost[i][j]=cost[i][j]+v[k]-v[mid];

}

for(i=0;i<=n;i++)

for(j=0;j<=m;j++)

w[i][j]=max;

w[0][0]=0;

for(i=0;i<=n;i++)

for(j=0;j<=m;j++)

if(w[i][j]

{

for(k=1;k<=m-j;k++)

{

q=w[i][j]+cost[j+1][j+k];

if(w[i+1][j+k]>q)

w[i+1][j+k]=q;

}

}

printf(“%dn”, w[n][m]);} return 0;}

18: pku acm 1015 Jury Compromise

題目大意:在遙遠(yuǎn)的國(guó)家佛羅布尼亞,嫌犯是否有罪,須由陪審團(tuán)決定。陪審團(tuán)是由法官?gòu)墓娭刑暨x的。先隨機(jī)挑選n個(gè)人作為陪審團(tuán)的候選人,然后再?gòu)倪@n個(gè)人中選m人組成陪審團(tuán)。選m人的辦法是:控方和辯方會(huì)根據(jù)對(duì)候選人的喜歡程度,給所有候選人打分,分值從0到20。為了公平起見,法官選出陪審團(tuán)的原則是:選出的m個(gè)人,必須滿足辯方總分和控方總分的差的絕對(duì)值最小。如果有多種選擇方案的辯方總分和控方總分的之差的絕對(duì)值相同,那么選辯控雙方總分之和最大的方案即可。

分析:顯然本題如不用DP的話,顯然會(huì)超時(shí)。我們將第i個(gè)人的辯方和控方的差記錄在sub[i]中,將第i個(gè)人的辯方和控方的和記錄在plus[i]中,現(xiàn)在用f(j,k)表示取j個(gè)侯選人中,辯控和最大的那個(gè)方案。如果沒法選j個(gè)人使其控辯差為k的話,令f(j,k)=-1;本題的要求選出m個(gè)人,即最終解為f(m,k),(-21*m<=k<=21*m)其中k的絕對(duì)值最小且有解。顯然f(j,k)是某個(gè)可行方案f(j-1,x)(-21*m<=x<=21*m)演變而來。可行方案f(j-1,x)演變成f(j,k)的條件是:存在某個(gè)侯選人i,它在方案f(j-1,x)中沒有被選上,且x+sub[i]=k,并且在所有滿足上述條件的方案中,f(j-1,x)+plus[i]最大。此時(shí)f(j-1,x)+plus[i]=f(j,k)。在上述推導(dǎo)中,另一個(gè)難點(diǎn)是如何標(biāo)記i是不是已經(jīng)在方案f(j-1,x)中。此時(shí),我們可以用一個(gè)path(j,k)來記錄相應(yīng)的f(j,k)中最后選的人。例如上面的,則path(j,k)=i;倒數(shù)第二個(gè)人選的編號(hào)為path(j-1,k-sub[i]),依次類推,我們就能求出某個(gè)方案中所有人的編號(hào)。實(shí)際解題中,則于控辯差有可能為負(fù),由于控辯差的范圍為[-21*m,21*m]我們可將所有控辯差加上m*21來解決,保證其值為正。#include #include #include using namespace std;

int m,n;int f[21][850];int path[21][850];int PLUS[500],sub[500],ans[21],la,size;int main(){

int i,ii,jj,j,k,a,b,test=1;

while(cin>>n>>m&&n+m)

{

size=21*m;

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

{

cin>>a>>b;

PLUS[i]=a+b;

sub[i]=a-b;

}

memset(f,-1,sizeof(f));

memset(path,-1,sizeof(path));

f[0][size]=0;path[0][size]=0;

for(i=1;i<=n;i++)//先算出第1個(gè)人的編號(hào)

{

if(f[1][size+sub[i]]

{

path[1][size+sub[i]]=i;

f[1][size+sub[i]]=PLUS[i];

}

}

for(i=1;i

{

for(j=0;j<2*size;j++)

{

if(path[i][j]>=0)

{

for(k=1;k<=n;k++)

{

if(f[i+1][j+sub[k]]

{

for(jj=i,ii=j;jj>=1;jj--)//順藤摸瓜.判斷第k個(gè)人有沒有出現(xiàn)過

{

if(path[jj][ii]==k)break;

ii-=sub[path[jj][ii]];

}

if(jj<1)

{

path[i+1][j+sub[k]]=k;

f[i+1][j+sub[k]]=f[i][j]+PLUS[k];

}

}

}

}

}

}

for(j=0;j<=2*size;j++)//取絕對(duì)值最小的作為最優(yōu)解

{

if(f[m][size+j]>=0||f[m][size-j]>=0)

{

if(f[m][size+j]>f[m][size-j])

i=size+j;

else i=size-j;

break;

}

}

cout<<“Jury #”<

cout<<“Best jury has value ”<<(f[m][i]+i-size)/2<<“ for ”<<(f[m][i]-i+size)/2<<“ for defence:”<

la=0;

for(j=m,k=i;j>=1;j--)

{

ans[la++]=path[j][k];

k-=sub[ans[la-1]];

}

sort(ans,ans+la);//排序輸出

for(i=0;i

cout<<“ ”<

cout<

}

return 0;

prosecution and value }

19: hdoj 2546飯卡

電子科大本部食堂的飯卡有一種很詭異的設(shè)計(jì),即在購(gòu)買之前判斷余額。如果購(gòu)買一個(gè)商品之前,卡上的剩余金額大于或等于5元,就一定可以購(gòu)買成功(即使購(gòu)買后卡上余額為負(fù)),否則無法購(gòu)買(即使金額足夠)。所以大家都希望盡量使卡上的余額最少。

某天,食堂中有n種菜出售,每種菜可購(gòu)買一次。已知每種菜的價(jià)格以及卡上的余額,問最少可使卡上的余額為多少。Input 多組數(shù)據(jù)。對(duì)于每組數(shù)據(jù):

第一行為正整數(shù)n,表示菜的數(shù)量。n<=1000。

第二行包括n個(gè)正整數(shù),表示每種菜的價(jià)格。價(jià)格不超過50。第三行包括一個(gè)正整數(shù)m,表示卡上的余額。m<=1000。n=0表示數(shù)據(jù)結(jié)束。

Output 對(duì)于每組輸入,輸出一行,包含一個(gè)整數(shù),表示卡上可能的最小余額。Sample Input 1 50 5 10 1 2 3 2 1 1 2 3 2 1 50 0 Sample Output-45 32

#include

#include

using namespace std;

int a[1002];

int b[1002];

void dfs(int x);

int m;

int sum,num,ans,flag;

int main()

{

int i,j,k,n,t;

while(scanf(“%d”,&n)!=EOF && n)

{

memset(b,0,sizeof(b));

sum = 0;

for(i=0;i

{

scanf(“%d”,&a[i]);

sum += a[i];

}

scanf(“%d”,&m);

if(sum+5 <= m)//如果余額很大的情況

{

printf(“%dn”,m-sum);

continue;

}

if(m < 5)//如果本來的余額小于5那么就不用計(jì)算了

{

printf(“%dn”,m);

continue;

}

sort(a,a+n);

//開始遍歷:

//找到臨界大于m-5的最小的和

ans = 0;

num = m-5;

for(i=n-2;i>=0;i--)

{

int maxnum = 0;

for(j=i+1;j<=n-2;j++)

{

if((b[j] > maxnum)&&(a[i]+b[j]<=num))

maxnum = b[j];

}

if(a[i]+maxnum == num)

{

ans = num;

break;

}

else if(a[i]+maxnum < num)

{

b[i] = a[i]+maxnum;

}

if(b[i] > ans)

ans = b[i];

}

printf(“%dn”,m-ans-a[n-1]);

}

return 0;

}

20:pku 1837 Balance

輸入一個(gè)天平若干(<=20)掛鉤的位置,將若干(<=20)砝碼掛到天平上,問有多少種使天平掛平衡的方法。

解題思路:

用一個(gè)二維數(shù)組a[x][y+mid]記錄掛x個(gè)砝碼時(shí)到y(tǒng)這個(gè)值的方法數(shù),將砝碼一一掛上,最后記錄所有砝碼都掛上時(shí)的t[x][MID]的值,詳見代碼。狀態(tài)方程:a[i][j+value[i]*hook[k]]+=a[i-1][j];背包問題

#include “stdio.h” #include “stdlib.h” #define MID 7500 int a[21][2*MID];int val[21];int hook[21];int main(){

int m,n;

int i,j,k;

while(scanf(“%d%d”,&m,&n)!=EOF)

{

memset(a,0,sizeof(a));

for(i = 1;i<=m;i++)

scanf(“%d”,&hook[i]);

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

scanf(“%d”,&val[i]);

for(j = 1;j<=m;j++)

a[1][val[1]*hook[j]+MID]++;

for(i =2;i<=n;i++)

for(j = 0;j<=2*MID;j++)

for(k = 1;k<=m;k++)

if(a[i-1][j]!=0)

{

a[i][j+val[i]*hook[k]]+=a[i-1][j];

}

printf(“%dn”,a[n][MID]);

}

return 0;}

21: pku 3267 The Cow Lexicon

題目意思就是給出一個(gè)字符序列,同時(shí)給出已知的字符序列(單詞),問至少需要去掉多少個(gè)字符之后能夠?qū)⒔o出的字符序列變成已知的字符序列(單詞)的組合(根據(jù)題目意思,沒有字符是已知字符序列組合的一種情況)。

可以用s[i]表示從第一個(gè)字符到第i個(gè)字符中,滿足題目要求去掉的最少字符數(shù)。那么s[i]=min(num[k,i]+s[k-1]),其中num[k,i]表示從第k個(gè)字符到第i個(gè)字符匹配到某一個(gè)單詞時(shí)所需要的去掉的最少字符數(shù)。當(dāng)然匹配時(shí)是需要窮舉所有的單詞的。匹配的時(shí)候如果從前往后比較的話,需要加入剪枝(如果k+len[j]〉i的話肯定就是不行的),這樣的話就可以采取從后往前的比較方式,這樣之前需要將每個(gè)單詞的長(zhǎng)度保存到len[j]當(dāng)中。

#include #include #include “string.h” using namespace std;int main(int argc, char *argv[]){ char word[601][30],str[305];int i,j,k,num,s[305],min,len[601],m,l,pos_str,pos_word;while(scanf(“%d%d”,&m,&l)!=EOF){

scanf(“%s”,str+1);

for(i=1;i<=m;i++){

scanf(“%s”,word[i]+1);

len[i]=strlen(word[i]+1);

}

s[0]=0;

for(i=1;i<=l;i++){

min=i;

for(j=1;j<=m;j++){

pos_str=i;

pos_word=len[j];

num=0;

while(pos_str>=1&&pos_word>=1){

if(str[pos_str]==word[j][pos_word]){

pos_str--;

pos_word--;

}

else {

pos_str--;

num++;

}

}

if(pos_word<=0 && min>num+s[pos_str]){

min=num+s[pos_str];

}

}

s[i]=min;

}

printf(“%dn”,s[l]);

} system(“PAUSE”);

return 0;} 22:Pku 1742 Coins

編寫一個(gè)程序,讀入n,m。有幣值A(chǔ)1、A2、A3…、An的硬幣,對(duì)應(yīng)各有C1、C2、C3、…、Cn數(shù)量的硬幣,問它們能夠在1~m元中組合成多少中不同的幣值?

#include using namespace std;int a[110],c[110];int dp[2][100010],flag[100010],flagans[100010];int main(){ int n,m;while(scanf(“%d%d”,&n,&m)!=EOF&&!(n==0&&m==0)){

memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++)scanf(“%d”,&a[i]);for(int i=1;i<=n;i++)

scanf(“%d”,&c[i]);for(int i=0;i<2;i++)dp[i][0]=1;memset(flag,0,sizeof(flag));memset(flagans,0,sizeof(flagans));int from=0,to=1;for(int i=1;i<=n;i++){

memset(flag,0,sizeof(flag));

for(int j=1;j<=m;j++)

{

dp[to][j]=dp[from][j];

if(dp[to][j]==0&&j>=a[i]&&dp[to][j-a[i]]&&flag[j-a[i]]+1<=c[i])

{

dp[to][j]=1;

flagans[j]=1;

flag[j]=flag[j-a[i]]+1;

}

}

int temp;

temp=from;

from=to;

to=temp;} int ans=0;for(int i=1;i<=m;i++){

// cout<

ans+=flagans[i];} printf(“%dn”,ans);} system(“pause”);return 0;}

第二篇:動(dòng)態(tài)規(guī)劃教案

吉林師范大學(xué)計(jì)算機(jī)學(xué)院

課 程 名 稱 院系

級(jí)

C 程序設(shè)計(jì)(算法部分)

計(jì)算機(jī)學(xué)院計(jì)算機(jī)科學(xué)與技術(shù)09級(jí)

教研室(系、實(shí)驗(yàn)室)計(jì)算機(jī)基礎(chǔ)教研室5101 授 課 班 級(jí) 09計(jì)算機(jī)科學(xué)與技術(shù)3班 實(shí)習(xí)

鄭言

系指導(dǎo)教師

滕國(guó)文

吉林師范大學(xué)計(jì)算機(jī)學(xué)院

二○一二年四月二十五日(星期三5,6節(jié))

課型章節(jié):

動(dòng)態(tài)規(guī)劃基本思想

基要本參教考材資和料主:

算法設(shè)計(jì)與分析》 教學(xué)目的:

本課程以C語(yǔ)言為教授程序設(shè)計(jì)的描述語(yǔ)言,結(jié)合語(yǔ)言介紹程序設(shè)計(jì)的基本原理、技巧和方法。主要講授內(nèi)容包括程序設(shè)計(jì)動(dòng)態(tài)規(guī)劃基本概念,動(dòng)態(tài)規(guī)劃的基本步驟,動(dòng)態(tài)規(guī)劃問題的特征。通過本課程的學(xué)習(xí),為算法更好的學(xué)習(xí),以及能用計(jì)算機(jī)解決一些實(shí)際問題打下堅(jiān)實(shí)的基礎(chǔ)。教學(xué)基本要求:

掌握C語(yǔ)言中動(dòng)態(tài)規(guī)劃的基本概念,動(dòng)態(tài)規(guī)劃的基本步驟,動(dòng)態(tài)規(guī)劃問題的特征。并能熟練使用C語(yǔ)言動(dòng)態(tài)規(guī)劃思想解決一些簡(jiǎn)單程序問題;掌握一些基本算法結(jié)構(gòu)及相關(guān)方法;熟悉程序設(shè)計(jì)的思想和編程技巧。重點(diǎn):

動(dòng)態(tài)規(guī)劃基本概念,動(dòng)態(tài)規(guī)劃的基本步驟,動(dòng)態(tài)規(guī)劃問題的特征。難點(diǎn): 動(dòng)態(tài)規(guī)劃的基本步驟 課型:

理論課 教法:

1.多媒體講解 2.舉例講解 教學(xué)內(nèi)容及過程: 1.課前回顧:

枚舉法: 在進(jìn)行歸納推理時(shí),如果逐個(gè)考察了某類事件的所有可能情況,因而得出一般結(jié)論,那么這結(jié)論是可靠的,這種歸納方法叫做枚舉法.

2.數(shù)塔問題

有形如下圖所示的數(shù)塔,從頂部出發(fā),在每一結(jié)點(diǎn)可以選擇向左走或是向右走,一直走到底層,要求找出一條路徑,使路徑上的值最大。簡(jiǎn)單的進(jìn)行選舉方法的引導(dǎo),讓同學(xué)們主動(dòng)思考到動(dòng)態(tài)規(guī)劃的思想上了。考慮一下:

從頂點(diǎn)出發(fā)時(shí)到底向左走還是向右走應(yīng)取決于是從左走能取到最大值還是從右走能取到最大值,只要左右兩道路徑上的最大值求出來了才能作出決策。

同樣,下一層的走向又要取決于再下一層上的最大值是否已經(jīng)求出才能決策。這樣一層一層推下去,直到倒數(shù)第二層時(shí)就非常明了。

如數(shù)字2,只要選擇它下面較大值的結(jié)點(diǎn)19前進(jìn)就可以了。所以實(shí)際求解時(shí),可從底層開始,層層遞進(jìn),最后得到最大值。

結(jié)論:自頂向下的分析,自底向上的計(jì)算。#include #include int max(int x,int y){ if(x>y)

return x;else

return y;} main(){ int a[100][100];int i,j,n;scanf(“%d”,&n);for(i=0;i

for(j=0;j<=i;j++)

scanf(“%d”,&a[i][j]);for(i=n-2;i>=0;i--)

for(j=0;j<=i;j++)

{

a[i][j]+=max(a[i+1][j],a[i+1][j+1]);

} printf(“%dn”,a[0][0]);} 3.總結(jié)“動(dòng)態(tài)規(guī)劃的基本思想”

如果各個(gè)子問題不是獨(dú)立的,不同的子問題的個(gè)數(shù)只是多項(xiàng)式量級(jí),如果我們能夠保存已經(jīng)解決的子問題的答案,而在需要的時(shí)候再找出已求得的答案,這樣就可以避免大量的重復(fù)計(jì)算。由此而來的基本思路是,用一個(gè)表記錄所有已解決的子問題的答案,不管該問題以后是否被用到,只要它被計(jì)算過,就將其結(jié)果填入表中。

4.總結(jié)“動(dòng)態(tài)規(guī)劃的基本步驟”

動(dòng)態(tài)規(guī)劃算法通常用于求解具有某種最優(yōu)性質(zhì)的問題。在這類問題中,可能會(huì)有許多可行解。每一個(gè)解都對(duì)應(yīng)于一個(gè)值,我們希望找到具有最優(yōu)值(最大值或最小值)的那個(gè)解。設(shè)計(jì)一個(gè)動(dòng)態(tài)規(guī)劃算法,通常可以按以下幾個(gè)步驟進(jìn)行:

(1)找出最優(yōu)解的性質(zhì),并刻畫其結(jié)構(gòu)特征。(2)遞歸地定義最優(yōu)值。

(3)以自底向上的方式計(jì)算出最優(yōu)值。

(4)根據(jù)計(jì)算最優(yōu)值時(shí)得到的信息,構(gòu)造一個(gè)最優(yōu)解。

其中(1)——(3)步是動(dòng)態(tài)規(guī)劃算法的基本步驟。在只需要求出最優(yōu)值的情形,步驟(4)可以省去。若需要求出問題的一個(gè)最優(yōu)解,則必須執(zhí)行步驟(4)。此時(shí),在步驟(3)中計(jì)算最優(yōu)值時(shí),通常需記錄更多的信息,以便在步驟(4)中,根據(jù)所記錄的信息,快速構(gòu)造出一個(gè)最優(yōu)解。

5.總結(jié)“動(dòng)態(tài)規(guī)劃問題的特征”

動(dòng)態(tài)規(guī)劃算法的有效性依賴于問題本身所具有的兩個(gè)重要性質(zhì):

1、最優(yōu)子結(jié)構(gòu):當(dāng)問題的最優(yōu)解包含了其子問題的最優(yōu)解時(shí),稱該問題具有最優(yōu)子結(jié)構(gòu)性質(zhì)。

2、重疊子問題:在用遞歸算法自頂向下解問題時(shí),每次產(chǎn)生的子問題并不總是新問題,有些子問題被反復(fù)計(jì)算多次。動(dòng)態(tài)規(guī)劃算法正是利用了這種子問題的重疊性質(zhì),對(duì)每一個(gè)子問題只解一次,而后將其解保存在一個(gè)表格中,在以后盡可能多地利用這些子問題的解。6.思考:

《免費(fèi)餡餅》 題目描述: 都說天上不會(huì)掉餡餅,但有一天gameboy正走在回家的小徑上,忽然天上掉下大把大把的餡餅。說來gameboy的人品實(shí)在是太好了,這餡餅別處都不掉,就掉落在他身旁的10米范圍內(nèi)。餡餅如果掉在了地上當(dāng)然就不能吃了,所以gameboy馬上卸下身上的背包去接。但由于小徑兩側(cè)都不能站人,所以他只能在小徑上接。由于gameboy平時(shí)老呆在房間里玩游戲,雖然在游戲中是個(gè)身手敏捷的高手,但在現(xiàn)實(shí)中運(yùn)動(dòng)神經(jīng)特別遲鈍,每秒種只有在移動(dòng)不超過一米的范圍內(nèi)接住墜落的餡餅。現(xiàn)在給這條小徑如圖標(biāo)上坐標(biāo):

為了使問題簡(jiǎn)化,假設(shè)在接下來的一段時(shí)間里,餡餅都掉落在0-10這11個(gè)位置。開始時(shí)gameboy站在5這個(gè)位置,因此在第一秒,他只能接到4,5,6這三個(gè)位置中期中一個(gè)位置上的餡餅。問gameboy最多可能接到多少個(gè)餡餅?(假設(shè)他的背包可以容納無窮多個(gè)餡餅)

#include using namespace std;int a[100001][11];int max(int x,int y,int z){ if(x>y)if(x>z)return x;else return z;else if(y>z)return y;else return z;} int main(){ int i,j,f,n,x,y;while(cin>>n){ if(n==0)break;memset(a,0,sizeof(a));f=0;for(i=0;i>y>>x;a[x][y]++;if(x>f)f=x;} for(i=f-1;i>=0;i--){ for(j=0;j<11;j++)if(j>0&&j<10)a[i][j]+=max(a[i+1][j-1],a[i+1][j],a[i+1][j+1]);else if(j==0)a[i][j]+=max(0,a[i+1][j],a[i+1][j+1]);else a[i][j]+=max(0,a[i+1][j-1],a[i+1][j]);} cout<

7.課后作業(yè)

杭電ACM 1003、1466、1087、1159、1176、1058、1069、2059、2084

第三篇:課文題目中的標(biāo)點(diǎn)

課文題目中的標(biāo)點(diǎn)

我們學(xué)習(xí)的課文中,好些題目上有標(biāo)點(diǎn)符號(hào),它們大致可分為以下幾種:

一、引用文中的一句話

如《“你們想錯(cuò)了”》、《“兄弟便是朱德”》、《“我是你的兒子”》這三篇課文的題目是直接引用文中的一句話,因此加上了引號(hào)。

二、表示語(yǔ)句的停頓

課文題目中如有停頓,必須用逗號(hào)隔開,如《再見了,親人》、《別了,我愛的中國(guó)》、《火警,119》、《祖國(guó),我終于回來了》、《延安,我把你追尋》等。

三、表示某種特殊語(yǔ)意

題目中有某種特殊語(yǔ)意時(shí),也常用引號(hào),如《“私塾先生”》、《我的“自白”書》等。其中的“私塾先生”指的是陳毅同志。

第四篇:動(dòng)態(tài)規(guī)劃作業(yè)

作業(yè) 1 1 動(dòng)態(tài)規(guī)劃練習(xí):

為保證某一設(shè)備的正常運(yùn)轉(zhuǎn),需備有三種不同的零件 E 1 , E 2, E 3

。若增加備用零件的數(shù)量,可提高設(shè)備正常運(yùn)轉(zhuǎn)的可靠性,但增加了費(fèi)用,而投資額僅為8000 元。已知備用零件數(shù)與它的可靠性和費(fèi)用的關(guān)系如表1 所示。

現(xiàn)要求在既不超出投資額的限制,又能盡量提高設(shè)備運(yùn)轉(zhuǎn)的可靠性的條件下,問各種零件的備件數(shù)量應(yīng)是多少為好?要寫出計(jì)算程序。

解:

設(shè)投資順序?yàn)?E1,E2,E3,階段編號(hào)逆向編號(hào),即第一階段計(jì)算給E3 投資的效果。設(shè)ks 為第 k 階段的剩余款,kx 為第 k 階段的撥款額,狀態(tài)轉(zhuǎn)移方程為k k kx s s ? ??1,目標(biāo)函數(shù)為)1()1()1(max3 2 1P P P f ? ? ? ? ? ? ,其中1P,2P,3P 分別為 E1,E2,E3 增加的可靠性 第一階段:對(duì) E3 的投資效果 決策表:

s1x1 0 2 3 4 *1x

f1 0 1

0 1 1 1

0 1 2 1 1.1

1.1 3 1 1.1 1.21.2 4 1 1.1 1.2 1.7 4 1.7 1 1.1 1.2 1.7 4 1.7 6 1 1.1 1.2 1.7 4 1.7 7 1 1.1 1.2 1.7 4 1.7 8 1 1.1 1.2 1.7 4 1.7

第二階段,對(duì) E2 的投資效果 由于 E1 最多只需 3000,故 52?? s 千 決策表:

s2x2 0 3 5 6 *2x

f2 5 1.7 1.32 1.51.5 6 1.7 1.44 1.5 1.9 6 1.9 7 1.7 2.04 1.65 1.9 3 2.04 8 1.7 2.04 1.8 2.09 6 2.09 第三階段:對(duì) E1 的投資效果 決策表: s3x3 0 2 3 4 *3x

R3 8 2.09 2.09 1.8 0.7 0,2 2.09 回溯:有兩組最優(yōu)解(1)x3=0,x2=3,x1=2,maxf=2.09(2)x3=1,x2=3,x1=0,maxf=2.092 層次分析法練習(xí):你已經(jīng)去過幾家主要的摩托車商店,基本確定將從三種車型

中選購(gòu)一種,你選擇的標(biāo)準(zhǔn)主要有:價(jià)格、耗油量大小、舒適程度和外觀美觀情況。經(jīng)反復(fù)思考比較,構(gòu)造了它們之間的成對(duì)比較判斷矩陣。

三種車型(記為 a , b , c)關(guān)于價(jià)格、耗油量、舒適程度和外表美觀情況的成對(duì)比較判斷矩陣為:

(1)根據(jù)上述矩陣可以看出四項(xiàng)標(biāo)準(zhǔn)在你心目中的比重是不同的,請(qǐng)按由重到輕順序?qū)⑺鼈兣懦觥?/p>

(2)哪輛車最便宜、哪輛車最省油、哪輛車最舒適、哪輛車最漂亮?(3)用層次分析法確定你對(duì)這三種車型的喜歡程度(用百分比表示)。

解:

(1)由重到輕依次是價(jià)格、耗油量、舒適程度和外表美觀情況(2)C 車最便宜,A 車最省油,A 車最舒適,B 車最漂亮(3)a、建立層次模型:

目標(biāo)層:選擇哪種車 準(zhǔn)則層:價(jià)格

耗油情況

舒適度

外表美觀度 方案層:A 車型

B 車型

C 車型 b、成對(duì)比較陣題目當(dāng)中已給出 c、計(jì)算權(quán)向量并做一致性檢驗(yàn) 運(yùn)行結(jié)果得到權(quán)向量為 w=(0.5820,0.2786,0.0899,0.0495),CR=0.0734<0.1,通過一致性檢驗(yàn) d、計(jì)算組合權(quán)向量。

由運(yùn)行結(jié)果得知方案層對(duì)目標(biāo)層的權(quán)重向量為(0.4091,0.4416,0.1493)

則可得出結(jié)論應(yīng)該選購(gòu) B 車型 附(代碼):

clc a=[1,3,7,8

1/3,1,5,5

1/7,1/5,1,3

1/8,1/5,1/3,1];%一致矩陣 [x,y]=eig(a);eigenvalue=diag(y);lamda=max(eigenvalue);ci1=(lamda-4)/3;cr1=ci1/0.9 w1=x(:,1)/sum(x(:,1))b1=[1,2,3;1/2,1,2;1/3,1/2,1];[x,y]=eig(b1);eigenvalue=diag(y);lamda=eigenvalue(1);ci21=(lamda-3)/2;cr21=ci21/0.58

w21=x(:,1)/sum(x(:,1))b2=[1

1/5

1/2;5

7;2

1/7

1];[x,y]=eig(b2);eigenvalue=diag(y);lamda=eigenvalue(1);ci22=(lamda-3)/2;cr22=ci22/0.58 w22=x(:,1)/sum(x(:,1))b3=[1

5;1/3

4;1/5

1/4

1];[x,y]=eig(b3);eigenvalue=diag(y);lamda=eigenvalue(1);ci23=(lamda-3)/2;cr23=ci23/0.58 w23=x(:,1)/sum(x(:,1))b4=[1

1/5

3;5

7;1/3

1/7

1];[x,y]=eig(b4);eigenvalue=diag(y);lamda=eigenvalue(1);ci24=(lamda-3)/2;cr24=ci24/0.58 w24=x(:,1)/sum(x(:,1))w_sum=[w21,w22,w23,w24]*w1 ci=[ci21,ci22,ci23,ci24];cr=ci*w1/sum(0.58*w1)

第五篇:文章題目中的標(biāo)點(diǎn)符號(hào)

正確使用標(biāo)題中的標(biāo)點(diǎn)?

學(xué)生在寫文章時(shí),僅做到在文內(nèi)正確使用標(biāo)點(diǎn)符號(hào)是遠(yuǎn)遠(yuǎn)不夠的。我在教學(xué)中發(fā)現(xiàn),一些學(xué)生在文章標(biāo)題中有濫用標(biāo)點(diǎn)的現(xiàn)象。因此,教師應(yīng)在文章標(biāo)題中如何使用標(biāo)點(diǎn)上對(duì)學(xué)生做正確引導(dǎo)。

一、文章題目是單句時(shí),句末不用句號(hào)

例:在山的那邊

二、文章題目是復(fù)句時(shí),中間可用逗號(hào),句末不用句號(hào)

例:十年,還一副尊嚴(yán)

三、題目表疑問語(yǔ)氣的用問號(hào),表感嘆語(yǔ)氣的用嘆號(hào) 例:還有人活著嗎? 短些,再短些!

四、題目中有停頓語(yǔ)氣的,可用以下方法處理

(1)用逗號(hào)、頓號(hào)或間隔號(hào)

例:啊,金色的秋天

黨在農(nóng)村的方針、政策、法規(guī)

夏夜·秋色

(2)“空格”表示停頓

例:關(guān)注學(xué)校關(guān)注家庭

(3)分行排列表語(yǔ)氣停頓

例:鍛煉心理品質(zhì)

培育健康心理

五、根據(jù)標(biāo)題內(nèi)容,也可用其它符號(hào)(如引號(hào)、破折號(hào)、省略號(hào)、書名號(hào)等等)

例:“諾曼底”號(hào)遇難記

下輩子,我們還當(dāng)母子

一位痛失兒子的母親自述

風(fēng)乍起……

徐霞客和《徐霞客游記》

承德縣第二中學(xué)

李桂琴

五道河中心校包軍

下載動(dòng)態(tài)規(guī)劃總結(jié)經(jīng)典題目(經(jīng)典中的經(jīng)典)word格式文檔
下載動(dòng)態(tài)規(guī)劃總結(jié)經(jīng)典題目(經(jīng)典中的經(jīng)典).doc
將本文檔下載到自己電腦,方便修改和收藏,請(qǐng)勿使用迅雷等下載。
點(diǎn)此處下載文檔

文檔為doc格式


聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),未作人工編輯處理,也不承擔(dān)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)有涉嫌版權(quán)的內(nèi)容,歡迎發(fā)送郵件至:645879355@qq.com 進(jìn)行舉報(bào),并提供相關(guān)證據(jù),工作人員會(huì)在5個(gè)工作日內(nèi)聯(lián)系你,一經(jīng)查實(shí),本站將立刻刪除涉嫌侵權(quán)內(nèi)容。

相關(guān)范文推薦

    旅游規(guī)劃項(xiàng)目中的旅游產(chǎn)品分類

    基本旅游產(chǎn)品主要包括觀光游覽與休閑度假兩方面。面向的客源為大眾客源,主要是通州與北京市及天津、河北周邊區(qū)縣的游人。主要指為游客觀光活動(dòng)所設(shè)計(jì)的一系列景區(qū)。在運(yùn)河水......

    規(guī)劃快題設(shè)計(jì)總結(jié)

    文章一 快題使用的工具: 鉛筆:2H,要買真的,最好是中華牌。(三只以上,如果你準(zhǔn)備用鉛筆畫透視圖,就要多準(zhǔn)備幾種規(guī)格,至少要有HB、2B) 鋼筆:如果你能畫一手出色的鋼筆畫,是很讓人羨慕......

    規(guī)劃考研快題總結(jié)(范文)

    規(guī)劃考研快題總結(jié) 一、前言 這份總結(jié),一方面是為了給將來可能開展的規(guī)劃快題培訓(xùn)做一個(gè)準(zhǔn)備,另一方面,也是作為自己考研經(jīng)歷的一個(gè)結(jié)尾章節(jié)。 以前者而言,需要讀者見諒的是,根據(jù)......

    宣傳工作動(dòng)態(tài)-江蘇社科規(guī)劃網(wǎng)

    江蘇宣傳工作動(dòng)態(tài) 社科基金成果專刊 第7期 中共江蘇省委宣傳部 2017年4月30日 進(jìn)一步發(fā)展江蘇綠色經(jīng)濟(jì)的對(duì)策建議 摘要:我省綠色經(jīng)濟(jì)發(fā)展已取得諸多成就,具體表現(xiàn)在產(chǎn)業(yè)結(jié)構(gòu)......

    『公務(wù)員考試』法律常識(shí)大全(答案在題目中)

    法律常識(shí)試題(一) 《行政許可法2》(★公務(wù)員考試肯定會(huì)考行政許可法★) 標(biāo)★者為重點(diǎn)關(guān)注知識(shí)點(diǎn),★★越多越重要1、(C)人民政府應(yīng)當(dāng)建立健全對(duì)行政機(jī)關(guān)實(shí)施行政許可的監(jiān)督制度,加......

    班級(jí)動(dòng)態(tài)總結(jié)

    金秋十月,碩果累累 時(shí)光匆匆,一轉(zhuǎn)眼開學(xué)已經(jīng)將近一個(gè)月了,我班同學(xué)在新學(xué)期表現(xiàn)出了大二學(xué)長(zhǎng)應(yīng)有的沉穩(wěn)與成熟。由于大一學(xué)年我班同學(xué)學(xué)習(xí)認(rèn)真努力,各種活動(dòng)積極參與,所以此次評(píng)......

    旅游規(guī)劃項(xiàng)目中的產(chǎn)品開發(fā)戰(zhàn)略研究

    什么是旅游規(guī)劃項(xiàng)目中的產(chǎn)品開發(fā)戰(zhàn)略?所謂旅游規(guī)劃項(xiàng)目中的產(chǎn)品開發(fā)戰(zhàn)略就是產(chǎn)品開發(fā)結(jié)構(gòu)化,即基礎(chǔ)旅游產(chǎn)品與特色旅游產(chǎn)品共存實(shí)行傳統(tǒng)旅游與新型旅游共同推進(jìn),基礎(chǔ)旅游與特色......

    校園規(guī)劃快題設(shè)計(jì)總結(jié)(精選)

    校園規(guī)劃快題設(shè)計(jì)總結(jié) ------一般為中學(xué)地塊的設(shè)計(jì) 總體的設(shè)計(jì)思路:大軸線(類似行政中心區(qū)的軸線設(shè)計(jì),高端),大水系,大廣場(chǎng)。 校園用地包括三個(gè)主要部分: (1) 建筑用地 (2) 運(yùn)動(dòng)場(chǎng)地 (3)......

主站蜘蛛池模板: 欧洲精品欧美精品| 色妺妺av爽爽影院| 国产亚洲精aa在线看| 18禁无遮挡羞羞污污污污网站| 久久国产av影片| 午夜成人性刺激免费视频| 免费国产黄网站在线观看可以下载| 亚洲熟悉妇女xxx妇女av| 苍井空一区二区波多野结衣av| 强壮的公次次弄得我高潮A片日本| 国产精品亚洲综合一区在线观看| 97久久人人超碰超碰窝窝| 久久婷婷五月综合色丁香| 久久综合少妇11p| 亚洲乳大丰满中文字幕| 色婷婷五月在线精品视频| 熟妇高潮喷沈阳45熟妇高潮喷| 免费国产污网站在线观看15| 亚洲色无码中文字幕手机在线| 国产成人精品日本亚洲18| 人人妻人人澡人人爽欧美精品| 国产高清乱码又大又圆| 国产精品久久久久aaaa| 成人无码视频在线观看大全| 伊人久久成人爱综合网| 亚洲精品天天影视综合网| 亚洲国产成人第一天堂| 无码人妻一区、二区、三区免费视频| 亚洲人成色44444在线观看| 人妻蜜桃久久AV一区| 18禁成年无码免费网站| 看黄a大片日本真人视频直播| 破了亲妺妺的处免费视频国产| 亚洲人成自拍网站在线观看| 日韩国产丝袜人妻一二区| 久久久久人妻一区精品色欧美| 亚洲成无码人在线观看| 国产亚洲欧美日韩在线一区| 亚洲国产成人av国产自| 色妞av永久一区二区国产av| 国产成人av一区二区三区在线|