社区讨论
玄关
P1880[NOI1995] 石子合并参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @m2c13u1y
- 此快照首次捕获于
- 2024/10/16 23:30 去年
- 此快照最后确认于
- 2025/11/04 17:02 4 个月前
虽然过了但是有疑惑
这串代码求得最小值都没问题,为什么求最大值的时候都多加了个总和
CPPsum[N]???
最后一行都减掉sum[N]就莫名过了#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;
int N;
int a[250];
int sum[300];
int dp1[250][250],dp2[250][250];
int dfs1(int l,int r)
{
if(dp1[l][r]) return dp1[l][r];
if(l==r || l>r) return dp1[l][r]=0; //加上l>r只是为了少讨论
int ans=INT_MAX;
for(int i=l;i<r;i++)
ans=min(ans,dfs1(l,i)+dfs1(i+1,r)+sum[r]-sum[l-1]); //合并两个区间所需+合并最终的石头所需,即l~r内所有石头之和
return dp1[l][r]=ans;
}
int dfs2(int l,int r)
{
if(dp2[l][r]) return dp2[l][r];
if(l==r || l>r) return dp2[l][r]=0; //加上l>r只是为了少讨论
int ans=-1;
for(int i=l;i<r;i++)
ans=max(ans,dfs2(l,i)+dfs2(i+1,r)+sum[r]-sum[l-1]); //合并两个区间所需+合并最终的石头所需,即l~r内所有石头之和
return dp2[l][r]=ans;
}
int main()
{
cin>>N;
for(int i=1;i<=N;i++) cin>>a[i];
sum[1]=a[1];
for(int i=1,j=1;i<=2*N;i++,j++)
{
if(i>N) j%=N;
sum[i]=a[j]+sum[i-1]; //区间扩大两倍
}
int minans=INT_MAX,maxans=-1;
for(int i=1;i<=N;i++)
{
for(int j=i+1;j<=N+i;j++) //分成i~j-1,j~i+N-1两个线性区间(i'==j,即j=N+i时包含(i~~j-1)整个区间)
{
minans=min(minans,dfs1(i,j-1)+dfs1(j,i+N-1)+sum[N]); //别忘加上总和
maxans=max(maxans,dfs2(i,j-1)+dfs2(j,i+N-1)+sum[N]);
}
}
cout<<minans<<endl<<maxans-sum[N];
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...