zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:蛋糕(区间DP)

    题目传送门(内部题34)


    输入格式

    第一行,一个正整数$n$。
    第二行,$n$个正整数$a_i$,保证$a_i$互不相等。


    输出格式

    一行一个整数表示间宫卓司得到的蛋糕大小总和的最大值。


    样例

    样例输入1:

    5
    2 8 1 10 9

    样例输出1:

    18

    样例输入2:

    8
    1 10 4 5 6 2 9 3

    样例输出2:

    26


    数据范围与提示

    样例1解释:

    最优解为:卓司君选第$2$块;雨咲酱选第$1$块;卓司君选第$5$块;雨咲酱选第$4$块;卓司君选第$3$块。

    数据范围:

    对于$32\%$的数据,$1leqslant nleqslant 20$。
    对于$64\%$的数据,$1leqslant nleqslant 30$。
    对于$100\%$的数据,$1leqslant nleqslant 2,000,1leqslant a_ileqslant {10}^9$,保证$a_i$互不相等。


    题解

    考虑$DP$,定义$dp[i][j]$表示拿完还上的区间$[i,j]$的蛋糕大小之和的最大值,根据长度的奇偶判断该谁拿即可。

    时间复杂度:$Theta(n^2)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    long long a[2010];
    long long dp[2010][2010];
    long long ans;
    int get(int x){if(x>n)x-=n;if(!x)x+=n;return x;}
    long long DP(int l,int r,int x)
    {
    	if(x>=n-1)return 0;
    	if(dp[l][r]!=-1)return dp[l][r];
    	dp[l][r]=0;
    	int ll=l,rr=r;
    	int lft=get(l-1),rht=get(r+1);
    	if(a[lft]>a[rht])l=lft;
    	else r=rht;
    	lft=get(l-1);
    	rht=get(r+1);
    	dp[ll][rr]=max(DP(lft,r,x+2)+a[lft],DP(l,rht,x+2)+a[rht]);
    	return dp[ll][rr];
    }
    int main()
    {
    	memset(dp,-1,sizeof(dp));
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    	for(int i=1;i<=n;i++)ans=max(ans,a[i]+DP(i,i,1));
    	printf("%lld",ans);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    Oracle查询今天的数据(昨天、本周...)
    Windows添加删除 route
    大三寒假学习进度(九)
    大三寒假学习进度(八)
    大三寒假学习进度(七)
    大三寒假学习进度(六)
    大三寒假学习进度(五)
    《软件架构师应该知道的97件事》阅读笔记(一)
    大三寒假学习进度(四)
    大三寒假学习进度(三)
  • 原文地址:https://www.cnblogs.com/wzc521/p/11494076.html
Copyright © 2011-2022 走看看