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.

五大常用算法之二:动态规划算法

你可能感兴趣的:(poj 3167 Cow Bowling【dp】)