洛谷:P1880 [NOI1995]石子合并(dp,普及+/提高)

题目:

在这里插入图片描述

代码:没看到环形,直接矩阵连乘!

#include<bits/stdc++.h>
using namespace std;
int A[200];
int D1[200][200];
int D2[200][200];
int m;
int f(int x,int y)
{
 if(x==y) return 0;
 if(D1[x][y]!=-1) return D1[x][y];
 D1[x][y]=1<<30;
 int sum=0;
 for(int i=x;i<=y;i++) sum+=A[i];
 for(int i=x;i<y;i++)
 {
  D1[x][y]=min(D1[x][y],f(x,i)+f(i+1,y)+sum);
 }
 return D1[x][y];
}
int f2(int x,int y)
{
 if(x==y) return 0;
 if(D2[x][y]!=-1) return D2[x][y];
 int sum=0;
 for(int i=x;i<=y;i++) sum+=A[i];
 for(int i=x;i<y;i++)
 {
  D2[x][y]=max(D2[x][y],f2(x,i)+f2(i+1,y)+sum);
 }
 return D2[x][y];
}
int main()
{
 cin>>m;
 memset(D1,-1,sizeof(D1));
 memset(D2,-1,sizeof(D2));
 for(int i=0;i<m;i++) cin>>A[i];
 cout<<f(0,m-1)<<endl<<f2(0,m-1);
}

上上述基础上,特别考虑最后一个放到第一个,第一个放到最后一个,由于原数组改变,无法记忆化了。

TEL:

#include<bits/stdc++.h>
using namespace std;
int A[200];
int D1[200][200];
int D2[200][200];
int m;
int f(int x,int y)
{
 if(x==y) return 0;
 if(x+1==y) return A[x]+A[y];
 //if(D1[x][y]!=-1) return D1[x][y];
 D1[x][y]=1<<30;
 int sum=0;
 for(int i=x;i<=y;i++) sum+=A[i];
 for(int i=x;i<y;i++)
 {
  D1[x][y]=min(D1[x][y],f(x,i)+f(i+1,y)+sum);
 }
 A[x]=A[x]+A[y];
 D1[x][y]=min(D1[x][y],A[x]+f(x,y-1));
 A[x]=A[x]-A[y];
 A[y]=A[x]+A[y];
 D1[x][y]=min(D1[x][y],A[y]+f(x+1,y));
 A[y]=A[y]-A[x];
 return D1[x][y];
}
int f2(int x,int y)
{
 if(x==y) return 0;
 if(x+1==y) return A[x]+A[y];
 //if(D1[x][y]!=-1) return D1[x][y];
 //D2[x][y]=1<<30;
 int sum=0;
 for(int i=x;i<=y;i++) sum+=A[i];
 for(int i=x;i<y;i++)
 {
  D2[x][y]=max(D2[x][y],f2(x,i)+f2(i+1,y)+sum);
 }
 A[x]=A[x]+A[y];
 D2[x][y]=max(D2[x][y],A[x]+f2(x,y-1));
 A[x]=A[x]-A[y];
 A[y]=A[x]+A[y];
 D2[x][y]=max(D2[x][y],A[y]+f2(x+1,y));
 A[y]=A[y]-A[x];
 return D2[x][y];
}
int main()
{
 cin>>m;
 memset(D1,-1,sizeof(D1));
 memset(D2,-1,sizeof(D2));
 for(int i=0;i<m;i++) cin>>A[i];
 cout<<f(0,m-1)<<endl<<f2(0,m-1);
}

看题解:环形很简单啊,来个二倍长度就可以啦。我是菜菜!第一个基础上改就OK;额、

#include<bits/stdc++.h>
using namespace std;
int A[400];
int D1[200][200];
int D2[200][200];
int m;
int f(int x,int y)
{
 if(x==y) return 0;
 if(D1[x][y]!=-1) return D1[x][y];
 D1[x][y]=1<<30;
 int sum=0;
 for(int i=x;i<=y;i++) sum+=A[i];
 for(int i=x;i<y;i++)
 {
  D1[x][y]=min(D1[x][y],f(x,i)+f(i+1,y)+sum);
 }
 return D1[x][y];
}
int f2(int x,int y)
{
 if(x==y) return 0;
 if(D2[x][y]!=-1) return D2[x][y];
 int sum=0;
 for(int i=x;i<=y;i++) sum+=A[i];
 for(int i=x;i<y;i++)
 {
  D2[x][y]=max(D2[x][y],f2(x,i)+f2(i+1,y)+sum);
 }
 return D2[x][y];
}
int main()
{
 cin>>m;
 memset(D1,-1,sizeof(D1));
 memset(D2,-1,sizeof(D2));
 for(int i=0;i<m;i++) 
 {
  cin>>A[i];
  A[i+m]=A[i];
 }
 int minn=1<<30,maxx=-1;
 for(int i=0;i<m;i++) 
 { 
  minn=min(f(i,i+m-1),minn);
  maxx=max(f2(i,i+m-1),maxx);
 }
  cout<<minn<<endl<<maxx;
}

猜你喜欢

转载自blog.csdn.net/weixin_42721412/article/details/107557319