10147. 「一本通 5.1 例 1」石子合并

10147. 「一本通 5.1 例 1」石子合并

 

 区间合并石子

每次合并相邻的两堆,求最大和最小能获得的值

cao。。一开始直接排序然后贪心,想了半天不知道哪里错了,原来是我眼瞎了抱歉

然后区间DP一下 

不会写循环  DP只会写搜索 嘻嘻

#include<bits/stdc++.h>
#define fi first
#define se second
#define io std::ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n){ll r=1%P;for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
int f[205][405];
int a[405];
int  dfs(int l,int r)
{
      if(l==r)
      return 0;
      if(f[l][r]!=INF)
      return f[l][r];
      int ans=INF;
      for(int i=l;i<r;i++)
      {
          ans=min(dfs(l,i)+dfs(i+1,r)+a[r]-a[l-1],ans);
      }
      return f[l][r]=ans;
}
int  dfs1(int l,int r)
{
      if(l==r)
      return 0;
      if(f[l][r])
      return f[l][r];
      int ans=0;
      for(int i=l;i<r;i++)
      {
          ans=max(dfs1(l,i)+dfs1(i+1,r)+a[r]-a[l-1],ans);
      }
      return f[l][r]=ans;
}
int main()
{
    int n;
    cin>>n;
    memset(f,INF,sizeof(f));
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        a[i+n]=a[i];
    }
    for(int i=1;i<=2*n;i++)
    {
        a[i]=a[i-1]+a[i];
    }
    int ans=INF;
    for(int i=1;i<=n;i++)
    {
        ans=min(dfs(i,i+n-1),ans);
    }
      cout<<ans<<endl;
    memset(f,0,sizeof(f));
    ans=0;
    for(int i=1;i<=n;i++)
    {
        ans=max(dfs1(i,i+n-1),ans);
    }
    cout<<ans<<endl;

}

 

上一篇:C++ —— 输入年份判断是否为闰年


下一篇:c