閱讀887 返回首頁    go 技術社區[雲棲]


poj 3167 Cow Bowling【dp】

這是一道最最基礎的dp題目,還記得當時看劉汝佳寫的《入門經典》時,就是拿的這個做例子,不過牛人當然是一筆帶過這麼簡單的例子。

狀態轉移方程為:dp[i][j]+=max(dp[i+1][j],dp[i+1][j+1]),如果要記錄路徑也簡單,另外再用一個數組專門存放原始數組就好

原三角形是

7
3 8
8 1 0
2 7 4 4
4 5 2 6 5


dp三角形是

30

23 21

20 13 10

7 12 10 10

4  5    2   6    5

如果要記錄路徑,就是從dp[1][1](即30)開始,2選1較大的,並在input數組中找到對應的數即可。如:

30-->23-->20-->12-->5            對應有:

7  -->3  -->8  -->7  -->5

思路很清晰


AC的代碼:

#include<stdio.h>

int dp[352][352];

inline int max(int a,int b){return a>b?a:b;}

int main()
{
    int n,i,j;

    scanf("%d",&n);

	//輸入
    for(i=1;i<=n;i++)
        for(j=1;j<=i;j++)
            scanf("%d",&dp[i][j]);

	//dp
    for(i=n-1;i>=1;i--)
        for(j=1;j<=i;j++)
            dp[i][j]=max(dp[i][j]+dp[i+1][j],dp[i][j]+dp[i+1][j+1]);

    printf("%d\n",dp[1][1]);

    return 0;
}


這道題用不用兩個數組都可以,不過記錄路徑就要用

用兩個數組就是要把第n層的數據複製過去


#include <stdio.h>

int input[360][360];
int dp[360][360];

inline int max(int a,int b){return a>b?a:b;}

int main()
{
	int n;
	scanf("%d",&n);

	//輸入
	int i,j;
	for(i=1;i<=n;i++)
		for(j=1;j<=i;j++)
			scanf("%d",&input[i][j]);


	for(i=1;i<=n;i++)
		dp[n][i]=input[n][i];
	//dp
	for(i=n-1;i>=1;i--)
		for(j=1;j<=i;j++)
			dp[i][j]=input[i][j]+max(dp[i+1][j],dp[i+1][j+1]);

	printf("%d\n",dp[1][1]);

	return 0;
}




複製過來兩個別人寫的很好的文章


1.poj 3176 的結題報告:POJ3176-Cow Bowling

2.

五大常用算法之二:動態規劃算法

最後更新:2017-04-03 14:53:41

  上一篇:go 麵試之如何回答關於算法設計的問題?
  下一篇:go 單鏈表的若幹問題