关于动态规划(Dynamic Programming)的若干思考 ------ [3.区间dp]

石子合并<1>

领域展开
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200;
int s[maxn];
int f[maxn][maxn], g[maxn][maxn];
int main() 
{
    int n;
    cin >> n;
    for (int i=1;i<=n; i++) 
	{
      	int t;
		cin>>t;
		s[i]=s[i-1]+t;  
    }
    memset(f,0x3f,sizeof(f));
	for(int i=1;i<=n;i++) f[i][i]=0;
    for (int len = 1; len <= n; len++) 
	{
        for (int i = 1; i+len-1 <= n ; i++) 
		{
            int j = i+len-1;
            for (int k = i; k < j; k++) 
			{
                f[i][j] = min(f[i][j], f[i][k] + f[k+1][j] + s[j] - s[i-1]);
                g[i][j] = max(g[i][j], g[i][k] + g[k+1][j] + s[j] - s[i-1]);
            }
            
        }
    }
   	cout << f[1][n] <<endl <<g[1][n];
    return 0;
}

石子合并<2>

领域展开
#include <bits/stdc++.h>
using namespace std;
const int maxn = 520;
int s[maxn];
int f[maxn][maxn], g[maxn][maxn];
int main() 
{
    int n,ans1 = 100000000, ans2 = 0;
    cin >> n;
    for (int i=1;i<=n; i++) 
	{
        cin >> s[i];
        s[i + n] = s[i];   
    }
    for (int i=1;i<= n << 1; i++) s[i] += s[i-1];   
    memset(f, 0x3f, sizeof(f));
    for(int i=1;i<=2*n;i++) f[i][i]=0;
    for (int len = 2; len <= n; len++) 
	{
        for (int i = 1; i + len - 1 <= n << 1; i++) 
		{
            int j = i+len-1;
            for (int k = i; k < j; k++) 
			{
                f[i][j] = min(f[i][j], f[i][k] + f[k+1][j] + s[j] - s[i-1]);
                g[i][j] = max(g[i][j], g[i][k] + g[k+1][j] + s[j] - s[i-1]);
            }
        }
    }
 	for (int i = 1; i <= n; i++) 
	{  
        ans1 = min(ans1, f[i][i + n - 1]);
        ans2 = max(ans2, g[i][i + n - 1]);
    }
    cout << ans1 <<endl <<ans2;
    return 0;
}

石子合并<3>

领域展开
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5000;
int s[maxn],a[maxn];
int g[maxn][maxn];
int n,ans;
int main() 
{
   
    cin >> n;
    for (int i=1;i<=n; i++) 
	{
        cin >> a[i];
        a[i + n] = a[i];   
    }
    for (int i=1;i<= n << 1; i++) s[i] = s[i-1]+a[i];   
    for (int len = 2; len <= n; len++) 
        for (int i = 1; i + len - 1 <= n << 1; i++) 
		{
            int j = i+len-1;
            g[i][j] = max(g[i][j-1], g[i+1][j] )+s[j]-s[i-1];
       	}
 	for (int i = 1; i <= n; i++) 
		ans = max(ans, g[i][i + n-1]);
    cout << ans;
    return 0;
}
posted @   十萧  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示