首页 > 其他分享 >51nod 1720 祖玛

51nod 1720 祖玛

时间:2024-09-10 19:25:44浏览次数:1  
标签:51nod dfs int 1720 数组 区间 祖玛 dp

51nod 1720 祖玛

这又是一个区间 dp,但这题又和其他的不一样,这题又用记忆化搜索,但是多学一种方法也没事,但其实用搜索后就模拟即可了。

#include<bits/stdc++.h>
using namespace std;

// 定义全局变量
int n; // 数组长度
int dp[505][505]; // dp[l][r] 表示在区间 [l, r] 之间的最优解
int a[1005]; // 存储输入的数组

// dfs 函数使用动态规划和递归来计算区间 [l, r] 的最小值
int dfs(int l, int r) {
    // 基本情况:如果左边界超过右边界,返回 1
    if (l > r) {
        return 1;
    }

    // 如果 dp[l][r] 已经被计算过,直接返回结果
    if (dp[l][r]) {
        return dp[l][r];
    }

    // 初始化 dp[l][r] 为一个很大的值,表示我们要找到最小值
    dp[l][r] = INT_MAX;

    // 枚举区间的分割点 i,将区间分为 [l, i] 和 [i+1, r] 两个部分
    for (int i = l; i < r; i++) {
        // 递归计算两部分的值,并更新最小值
        dp[l][r] = min(dp[l][r], dfs(l, i) + dfs(i + 1, r));
    }

    // 如果数组的左右边界元素相等,可以尝试通过减少一层区间来优化结果
    if (a[l] == a[r]) {
        dp[l][r] = min(dp[l][r], dfs(l + 1, r - 1)); 
    }

    // 返回在区间 [l, r] 的最优解
    return dp[l][r];
}

int main() {
    ios::sync_with_stdio(false); // 关闭同步以提高输入输出效率

    // 输入数组的长度
    cin >> n;
    
    // 输入数组元素,从下标 1 到 n
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }

    // 调用 dfs 函数求解区间 [1, n] 的最优值,并输出结果
    cout << dfs(1, n);

    return 0;
}

标签:51nod,dfs,int,1720,数组,区间,祖玛,dp
From: https://www.cnblogs.com/sadlin/p/18407010

相关文章

  • 51nod 3180 矩阵连乘
    51nod3180矩阵连乘感觉区间dp还是要感性理解,但好像区间有套路的,这和石子合并很像,就根据题意模拟。这个写法的区间比较巧妙,左右同时增加,相当于滑动窗口,因为一开始花费一个是0,所以注意dp的初始化。#include<bits/stdc++.h>usingnamespacestd;intn;......
  • 51nod 最大M子段和v1/v2/v3
    学习笔记最大M子段和V1\(N\)个整数组成的序列\(a[1],a[2],a[3],…,a[n]\),将这N个数划分为互不相交的\(M\)个子段,并且这\(M\)个子段的和是最大的。如果\(M>=N\)个数中正数的个数,那么输出所有正数的和。\(N,M<=5000\)。例如:\(-211-413-56-2\),分为\(2\)段,\(11......
  • 51nod 1051 最大子矩阵和
    51nod1051最大子矩阵和可以用前缀和容斥优化到\(O(n^4)\),但是不够进行如下图操作:将每一列的数值都压缩到一维的数组上,就转换为求最大字段和问题,时间复杂度\(O(n^3)\)。看看代码就知道了。#include<bits/stdc++.h>usingnamespacestd;#definelllonglongintn,m;......
  • 51nod 1243 排船的问题
    51nod1243排船的问题求最长绳子最短,考虑二分答案,判断时我们优先向左放,看是否能全放下。#include<bits/stdc++.h>usingnamespacestd;#definelllonglongintn,x,m;intpos[50005];intcheck(intmid){ intp=x;//偏差地图 intx2=x*2; intmx=m+x;//偏差地图 ......
  • 51nod 1020 逆序排列
    51nod1020逆序排列学习笔记其实要预处理,但唐的我非要每次都求一遍。设状态为\(dp[i][j]\)选了i个数逆序对数为j的排序种类数。首先初始化\(dp[i][0]=1\)即没有逆序对,转移方程\(dp[i][j]=dp[i-1][j]+dp[i-1][j-1]+……+dp[i-1][j-i]\)这是显然的(放上这个数,会产生的......
  • 51nod 1296 有限制的排列
    题目链接学习链接设状态\(dp[i][j]\)表示整数\([1,i]\)满足要求的排列中,最后一个数选\(j\)的排列数。开一个数组记录他的状态:把前面已选好的序列中大于等于\(j\)的数都加一后再把\(j\)加到后面。#include<bits/stdc++.h>usingnamespacestd;#definelllong......
  • 51nod 1050 循环数组最大子段和
    51nod1050循环数组最大子段和虽然是板子题,两种做法,我们先写一种,另一个咕咕。因为是循环,所以分为两种,中间的和两边的,中间的直接dp求最大,两边的转化一下就是总的数字和减去中间的最小数字和。#include<bits/stdc++.h>usingnamespacestd;#definelllonglonglla[500005]......
  • 51nod 1791 合法括号子段
    51nod1791原题链接因为在括号串固定的情况下,括号的匹配是固定不变的。所以对左括号进行匹配,p[i]表示与i这个括号相匹配的括号的位置,易得到dp方程ans[i]=ans[p[i]+1]+1,然后再从后先前一遍求和即可。#include<bits/stdc++.h>usingnamespacestd;#definelllonglongconst......
  • 51nod 石子分配
    可以发现步数限制把数轴变为了环。环之间不可以交换,环内相邻两点可以交换,然后我们只需要对每个环操作,最后累加。对于环上的每个石子堆,我们需要将其石子数调整到均值\(avg\)。因此,我们首先计算每个堆石子相对于\(avg\)的偏差,即\(nowa[i]-avg\)。因为相邻节点不一定能凑齐......
  • 51nod 1110 距离之和最小
    51nod1110距离之和最小考虑贪心取中位数,因为中位数到左边的点和右边的点的个数相同,更合理,权值的话可以转化为一个单点,然后没了。#include<bits/stdc++.h>usingnamespacestd;#definelllonglongintn;structss{ llx,w;}a[100005];boolcmp(ssg,ssh){ return......