poj2738 dp+递归

题目意思:对于一列数组,从两端取数字,第一个人取最优,第二个人选取左右边界中最大的数字


注意!!!当相等的时候取左边的( If there is a tie, remove the left end.


思路:刚开始想到两个左右两端各一个数字进行递归,但是发现第二个人会取一个数字,所以范围扩大,左右各两个数字,这样方便处理数字

然后比对,递归,见下面代码就好了


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

int a[1010],dp[1010][1010];
int ans;

int dfs(int f,int r)
{
    if(dp[f][r]!=-1)
        return dp[f][r];
    if(f+1==r)
        return dp[f][r]=abs(a[f]-a[r]);

    int temp1,temp2;
    if(a[f+1]>=a[r])
        temp1=dfs(f+2,r)+a[f]-a[f+1];
    else
        temp1=dfs(f+1,r-1)+a[f]-a[r];

    if(a[f]>=a[r-1])
        temp2=dfs(f+1,r-1)+a[r]-a[f];
    else
        temp2=dfs(f,r-2)+a[r]-a[r-1];

    return dp[f][r]=max(temp1,temp2);
}

int main()
{
    int n,coun=1;
    while(scanf("%d",&n),n)
    {
        memset(dp,-1,sizeof(dp));
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        printf("In game %d, the greedy strategy might lose by as many as %d points.\n",coun++,dfs(0,n-1));
    }

    return 0;
}


你可能感兴趣的:(poj2738 dp+递归)