本文主要是介绍P2858 [USACO06FEB] Treats for the Cows G/S 题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
P2858
题意
给一个数组。每天把最左或者最右的东西卖掉,第 i i i个东西,第 d a y day day天卖出的价格是 a [ i ] ∗ d a y a[i]*day a[i]∗day。
记忆化搜索
void dfs(int l,int r,int day,ll sum)
{if(v[l][r]>=sum)return;v[l][r]=sum;if(l>r)//这就是dp答案{ans=max(ans,sum);return;}if(l<=n)dfs(l+1,r,day+1,sum+a[l]*day);if(r>=1)dfs(l,r-1,day+1,sum+a[r]*day);
}
TLE 63
正解dp
通过写dfs
,我们可以发现对于状态dp[i][j]
他的下一个状态就是dp[i+1][j]
或dp[i][j-1]
。那么我们可以从当前状态出发计算下一个状态的值。我们可以用 d p [ i ] [ j ] dp[i][j] dp[i][j]表示从 [ i , j ] [i,j] [i,j]这个状态为起点的最大值。根据搜索的代码,答案就是 d p [ i ] [ i − 1 ] dp[i][i-1] dp[i][i−1]。记得long long
代码
#include<bits/stdc++.h>
#include<cstring>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<map>
#define ll long long
#define lhs printf("\n");
using namespace std;
const int N=1e5+10;
const int M=2024;
const int inf=0x3f3f3f3f;
ll a[N],n,dp[M][M],ans; //记得ll
int v[M][M];
void dfs(int l,int r,int day,ll sum)//记忆化
{if(v[l][r]>=sum)return;v[l][r]=sum;if(l>r){ans=max(ans,sum);return;}if(l<=n)dfs(l+1,r,day+1,sum+a[l]*day);if(r>=1)dfs(l,r-1,day+1,sum+a[r]*day);
}
int main()
{scanf("%lld",&n); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); for(int i=1;i<=n;i++){for(int j=n;j>=i;j--){int day=i-1+n-j+1;dp[i+1][j]=max(dp[i+1][j],dp[i][j]+a[i]*day);dp[i][j-1]=max(dp[i][j-1],dp[i][j]+a[j]*day); }}for(int i=1;i<=n;i++){ans=max(ans,dp[i][i-1]);}printf("%lld",ans);return 0;
}
AC记录
这篇关于P2858 [USACO06FEB] Treats for the Cows G/S 题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!