Sicily1176

递归超时的代码:

// Problem#: 1176
// Submission#: 2918390
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
using namespace std;

int A[1005];

int search(int l,int r)
{
    int maxn,temp;
    if (r-l==1) return A[l]>=A[r]?A[l]:A[r];
    if (A[l+1]>=A[r])
        maxn=search(l+2,r)+A[l];
    else
        maxn=search(l+1,r-1)+A[l];

    if (A[l]>=A[r-1])
    {
        temp=search(l+1,r-1)+A[r];
        return maxn>temp?maxn:temp;
    }
    else
    {
        temp=search(l,r-2)+A[r];
        return maxn>temp?maxn:temp;
    }
}

int main()
{
    int n,i;
    int counter=0;
    while (1)
    {
        counter++;
        scanf("%d",&n);
        if (!n) break;

        int total=0;
        for (i=0;i<n;i++)
        {
            scanf("%d",&A[i]);
            total+=A[i];
        }

        printf("In game %d, the greedy strategy might lose by as many as %d points.\n",counter,2*search(0,n-1)-total);
    }
}                                 

加个记忆化搜索AC:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
using namespace std;

int A[1005];
int dp[1005][1005];

int search(int l,int r)
{
	if (dp[l][r]) return dp[l][r];
	int maxn,temp;
	if (r-l==1) return dp[l][r]=A[l]>=A[r]?A[l]:A[r];
	if (A[l+1]>=A[r])
		maxn=search(l+2,r)+A[l];
	else
		maxn=search(l+1,r-1)+A[l];

	if (A[l]>=A[r-1])
	{
		temp=search(l+1,r-1)+A[r];
		maxn=maxn>temp?maxn:temp;
	}
	else
	{
		temp=search(l,r-2)+A[r];
		maxn=maxn>temp?maxn:temp;
	}
	return dp[l][r]=maxn;
}

int main()
{
	int n,i;
	int counter=0;
	while (1)
	{
		counter++;

		memset(dp,0,sizeof(dp));
		scanf("%d",&n);
		if (!n) break;

		int total=0;
		for (i=0;i<n;i++)
		{
			scanf("%d",&A[i]);
			total+=A[i];
		}

		printf("In game %d, the greedy strategy might lose by as many as %d points.\n",counter,2*search(0,n-1)-total);
	}
}

动态规划的写法:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
using namespace std;

int A[1005];
int dp[1005][1005];

int main()
{
	int n,i,j;
	int counter=0;
	while (1)
	{
		counter++;

		memset(dp,0,sizeof(dp));
		scanf("%d",&n);
		if (!n) break;

		int total=0;
		for (i=0;i<n;i++)
		{
			scanf("%d",&A[i]);
			total+=A[i];
		}

		for (i=0;i<n-1;i++)
			dp[i][i+1]=A[i]>A[i+1]?A[i]:A[i+1];

		int l,r,maxn;
		for (i=3;i<n;i+=2)
			for (j=0;j+i<n;j++)
			{
				l=j;
				r=j+i;
				if (A[l+1]>=A[r])
					maxn=A[l]+dp[l+2][r];
				else
					maxn=A[l]+dp[l+1][r-1];
				if (A[l]>=A[r-1])
					maxn=maxn>(A[r]+dp[l+1][r-1])?maxn:(A[r]+dp[l+1][r-1]);
				else
					maxn=maxn>(A[r]+dp[l][r-2])?maxn:(A[r]+dp[l][r-2]);
				dp[l][r]=maxn;
			}

		printf("In game %d, the greedy strategy might lose by as many as %d points.\n",counter,2*dp[0][n-1]-total);
	}
}

实际上动态规划和记忆化搜索的思想是一样的,对于这道题记忆化搜索要好写一些,而且避免了很多不必要的计算。

你可能感兴趣的:(Sicily1176)