【CCF】路径压缩 区间dp

【题意】

改编哈夫曼树,限制从左到右字母的编码按字典序递增

【思路】

  • 因为是二进制编码,所以是二叉树;
  • 因为是前缀码,所以每个字母都是叶子结点,不可能是内结点;
  • 因为要按字典序递增,所以只能是相邻的结点结合,且排在前面的在左边,排在后面的在右边;
  • 具有最优子结构性质:考虑f[i,j],可以由f[i,k]和f[k,j]转换而来,只要找一个根结点,然后左右孩子分别为f[i,k]和f[k,j]的根结点,即dp[i][j]=dp[i,k]+dp[k,j]+c

【AC】

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<queue>
 8
 9 using namespace std;
10 const int maxn=1e3+2;
11 const int inf=0x3f3f3f3f;
12 int a[maxn];
13 int dp[maxn][maxn];
14 int sum[maxn];
15 int n;
16 int main(){
17     while(~scanf("%d",&n)){
18         sum[0]=0;
19         for(int i=1;i<=n;i++){
20             scanf("%d",&a[i]);
21             sum[i]=sum[i-1]+a[i];
22         }
23         memset(dp,inf,sizeof(dp));
24         for(int i=1;i<=n;i++) dp[i][i]=0;
25         for(int l=2;l<=n;l++){
26             for(int i=1;i+l-1<=n;i++){
27                 int j=i+l-1;
28                 for(int k=i;k<j;k++){
29                     dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
30                 }
31             }
32         }
33         int ans=dp[1][n];
34         printf("%d\n",ans);
35
36     }
37     return 0;
38 }

原文地址:https://www.cnblogs.com/itcsl/p/9190142.html

时间: 2024-10-08 07:30:06

【CCF】路径压缩 区间dp的相关文章

【BZOJ-1068】压缩 区间DP

1068: [SCOI2007]压缩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 1001  Solved: 615[Submit][Status][Discuss] Description 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前位置左边没有M,则从串的开始算起)开始的解压结果(称为缓冲串). b

B1068 [SCOI2007]压缩 区间dp

这个题我状态想对了,但是转移错了...dp的代码难度都不大,但是思考含量太高了..不会啊,我太菜了. 其实这个题就是一个正常的区间dp,中间多了一个特判的转移就行了. 题干: Description 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小 写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前位置左边没 有M,则从串的开始算起)开始的解压结果(称为缓冲串). bcdcdcdcd可以压缩为bMcdRR

BZOJ 1068 [SCOI2007]压缩 区间DP

题意:链接 方法:区间DP 解析: MD写题解(吐槽)写到一半markdown挂了什么鬼! 要不要这样!你知道我的内心是什么样的吗! 吐槽,啊呸,写题解写到一半突然丢失了我的内心是崩溃的好吗! 来我们重新写题解(吐槽) 这道题我刚开始列了个瞎(和谐)动规(二维的裸区间) 加上乱七八糟的判断是否有M后,居然有交叉! 一定是我逻辑错误,对就是这样! 后来又是一顿瞎(和谐)搞之后,代码抽的爆炸,然后我一测,c-free挂掉- - 过了一个小时后,我选择死亡. 然后看了一眼hzw的题解. 看到那个三维之

hihoCoder #1320 : 压缩字符串 区间dp

/** 题目:hihoCoder #1320 : 压缩字符串 链接:https://hihocoder.com/problemset/problem/1320 描述 小Hi希望压缩一个只包含大写字母'A'-'Z'的字符串.他使用的方法是:如果某个子串 S 连续出现了 X 次,就用'X(S)'来表示. 例如AAAAAAAAAABABABCCD可以用10(A)2(BA)B2(C)D表示. 此外,这种压缩方法是可以嵌套的,例如HIHOHIHOCODERHIHOHIHOCODER可以表示成2(2(HIH

(review)zoj1276 区间dp+路径输出

[题解]:经典的区间dp,并且记录下了dp的path 因为是递归得到的path,所以递归压栈按从里到外的顺序得到path就可以了 输出嵌套括号部分很好的考察了对栈的理解,和递归执行的顺序. 注意题目输出中有的地方有空格 1 //zoj1276 路径输出用到了栈的思想,比较考验思维 2 #include<iostream> 3 #include<string.h> 4 #include<stdio.h> 5 #define maxn 13 6 using namespac

[BZOJ 1068] [SCOI2007] 压缩 【区间 DP 】

题目链接:BZOJ - 1068 题目分析 这种区间 DP 之前就做过类似的,也是字符串压缩问题,不过这道题稍微复杂一些. 需要注意如果某一段是 S1S1 重复,那么可以变成 M + Solve(S1) + R ,不过这个 Solve(S1) 中不能在中间有 M ,否则后面的 R 向前找到的 M 就不再是开头的 M 了. 代码 #include <iostream> #include <cstdio> #include <cstring> #include <al

POJ 1141 Brackets Sequence (区间dp 记录路径)

题目大意: 给出一种不合法的括号序列,要求构造出一种合法的序列,使得填充的括号最少. 思路分析: 如果只要求输出最少的匹配括号的数量,那么就是简单的区间dp dp[i][j]表示 i - j 之间已经合法了最少添加的括号数. 转移 就是 dp[i] [j] = min  (dp[i+1][j]+1 , dp[ i+ 1] [ k -1 ] + dp[k+1] [j] (i k 位置的括号匹配)) 其次我们要记录路径,你发现  如果 dp [i] [j] 是由 dp [i+1] [j] 转移过来的

HDU 4640 Island and study-sister(状态压缩DP+路径压缩)经典 旅行商问题

Island and study-sister Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 790    Accepted Submission(s): 273 Problem Description Members of ACM/ICPC teams of Fuzhou University always stay in th

bzoj 1068: [SCOI2007]压缩【区间dp】

神区间dp 设f[l][r][0]为在l到r中压缩的第一个字符为M,并且区间内只有这一个M,f[l][r][0]为在l到r中压缩的第一个字符为M,并且区间内有两个及以上的M 然后显然的转移是f[i][j][1]=min(f[i][k][0],f[i][k][1])+min(f[k+1][j][0],f[k+1][j][1])+1,f[i][j][0]=f[i][j][0],f[i][k][0]+j-k 然后考虑合并串,也就是当(l,mid),(mid+1,r)的串相等的时候,转移f[i][j][