usaco5.1.3 Musical Themes

基于MP2642GR-Z和PIC18F87K22的2S电池组主动均衡方案设计 在串联电池组中,电芯单体之间的容量与电压差异会导致“木桶效应”,整组可用容量受最弱电芯限制。主动均衡技术通过能量转移实现电芯间电压平衡,相比被动均衡以热量耗散的方式,具备更高效率和安全性。本文围绕基于 MP2642GR-Z 升降压功率级与 PIC18F87K22 单片机的 2S 电池组主动均衡方案,讲解系统设计、硬件电路、控制策略及实测数据,适用于 BMS、储能变流器及备用电源等场景,为工程师提供可复现的工程参考。 阅读详情

一 原题

Musical Themes
Brian Dean

A musical melody is represented as a sequence of N (1 <= N <= 5000) notes that are integers in the range 1..88, each representing a key on the piano. It is unfortunate but true that this representation of melodies ignores the notion of musical timing; but, this programming task is about notes and not timings.

Many composers structure their music around a repeating "theme", which, being a subsequence of an entire melody, is a sequence of integers in our representation. A subsequence of a melody is a theme if it:

  • is at least five notes long
  • appears (potentially transposed -- see below) again somewhere else in the piece of music
  • is disjoint from (i.e., non-overlapping with) at least one of its other appearance(s)
Transposed means that a constant positive or negative value is added to every note value in the theme subsequence.

Given a melody, compute the length (number of notes) of the longest theme.

One second time limit for this problem's solutions!

PROGRAM NAME: theme

INPUT FORMAT

The first line of the input file contains the integer N. Each subsequent line (except potentially the last) contains 20 integers representing the sequence of notes. The last line contains the remainder of the notes, potentially fewer than 20.

SAMPLE INPUT (file theme.in)

30
25 27 30 34 39 45 52 60 69 79 69 60 52 45 39 34 30 26 22 18
82 78 74 70 66 67 64 60 65 80

OUTPUT FORMAT

The output file should contain a single line with a single integer that represents the length of the longest theme. If there are no themes, output 0.

SAMPLE OUTPUT (file theme.out)

5
[The five-long theme is the last five notes of the first line and the first five notes of the second] 


二 分析

要求在一个长度最大为5000的串L中找到两个不相交的子串l1,l2,满足两个条件:(1)l1,l2长度相同(2)对应位置上的元素差为定值。
很容易想到把L中每个元素与前一个元素做差。我们只要求新数组中两个完全相同的子串就好了(有些处理不相交的细节注意一下)。
这道题usaco上的数据小了,可以用动态规划给一个O(n^2)的解法(见AC代码1),POJ上的数据给定字符串长度会到2e4,要用后缀数组才能过(见AC代码2)。

三 代码

运行结果1:
USER: Qi Shen [maxkibb3]
TASK: theme
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.000 secs, 4256 KB]
   Test 2: TEST OK [0.000 secs, 4256 KB]
   Test 3: TEST OK [0.000 secs, 4256 KB]
   Test 4: TEST OK [0.000 secs, 4256 KB]
   Test 5: TEST OK [0.000 secs, 4256 KB]
   Test 6: TEST OK [0.000 secs, 4256 KB]
   Test 7: TEST OK [0.000 secs, 4256 KB]
   Test 8: TEST OK [0.000 secs, 4256 KB]
   Test 9: TEST OK [0.011 secs, 4256 KB]
   Test 10: TEST OK [0.000 secs, 4256 KB]
   Test 11: TEST OK [0.108 secs, 4256 KB]
   Test 12: TEST OK [0.076 secs, 4256 KB]
   Test 13: TEST OK [0.086 secs, 4256 KB]
   Test 14: TEST OK [0.097 secs, 4256 KB]
   Test 15: TEST OK [0.086 secs, 4256 KB]

All tests OK.

Your program ('theme') produced all correct answers! This is yoursubmission #5 for this problem.Congratulations!


AC代码1(动态规划):
/* 
ID:maxkibb3 
LANG:C++ 
PROB:theme 
*/  

#include <cstdio>
#include <cstring>
#include <algorithm>
  
const int maxn = 2e4 + 10;  
  
int n, a[maxn], b[maxn], dp[2][maxn], ans;
  
int main() {
    freopen("theme.in", "r", stdin);
    freopen("theme.out", "w", stdout);
    scanf("%d", &n);  
    for (int i = 0; i < n; i++) {  
        scanf("%d", &a[i]);  
        if (i == 0) continue;  
        b[i] = a[i] - a[i - 1];  
    }
    
    for (int i = 1; i < n; i++) {  
        for (int j = i + 1; j < n; j++) {  
            if (b[j] == b[i]) {
                dp[1][j] = dp[0][j - 1] + 1;
                int tmp = std::min(dp[1][j], j - i - 1);
                if (tmp > ans) ans = tmp;
            }  
            else dp[1][j] = 0;  
        }  
        memcpy(dp[0], dp[1], sizeof(dp[1]));
    }
    if (ans < 4) printf("0\n");  
    else printf("%d\n", ans + 1);
    return 0;
}
运行结果2:

USER: Qi Shen [maxkibb3]
TASK: theme
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.000 secs, 5584 KB]
   Test 2: TEST OK [0.000 secs, 5584 KB]
   Test 3: TEST OK [0.000 secs, 5580 KB]
   Test 4: TEST OK [0.000 secs, 5580 KB]
   Test 5: TEST OK [0.000 secs, 5584 KB]
   Test 6: TEST OK [0.000 secs, 5580 KB]
   Test 7: TEST OK [0.000 secs, 5584 KB]
   Test 8: TEST OK [0.000 secs, 5580 KB]
   Test 9: TEST OK [0.000 secs, 5584 KB]
   Test 10: TEST OK [0.000 secs, 5584 KB]
   Test 11: TEST OK [0.000 secs, 5584 KB]
   Test 12: TEST OK [0.000 secs, 5584 KB]
   Test 13: TEST OK [0.000 secs, 5580 KB]
   Test 14: TEST OK [0.000 secs, 5584 KB]
   Test 15: TEST OK [0.000 secs, 5584 KB]

All tests OK.

Your program ('theme') produced all correct answers! This is yoursubmission #11 for this problem. Congratulations!

AC代码2(二分答案+后缀数组):
/*
ID: maxkibb3
LANG: C++
PROB: theme
*/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using std::string;
using std::sort;
using std::max;
using std::min;

#define local

const int maxn = 2e4 + 10;

int n, a[maxn], b[maxn];

// All indexes start from 0
struct SuffixArray {
    int len, str[maxn], sa[maxn], rank[maxn], height[maxn], bucket[maxn];

    struct RadixItem {
        int idx, key[2];

        RadixItem() {}
        RadixItem(int a, int b, int c) {
            idx = a, key[0] = b, key[1] = c;
        }

        bool operator == (const RadixItem &obj) const {
            return key[0] == obj.key[0] && key[1] == obj.key[1];
        }
    } items[maxn];
    
    void RadixSort() {
        int x;
        RadixItem tmp[maxn], *r1, *r2;
        for (x = 1, r1 = items, r2 = tmp; x >= 0; x--) {
            memset(bucket, 0, sizeof(bucket));
            for (int i = 0; i < len; i++) bucket[r1[i].key[x] + 1]++;
            for (int i = 1; i < maxn; i++) bucket[i] += bucket[i - 1];
            for (int i = len - 1; i >= 0; i--) r2[--bucket[r1[i].key[x] + 1]] = r1[i];
            r1 = tmp, r2 = items;
        }
        for (int i = 0, cnt = 0; i < len; i++) {
            rank[items[i].idx] = (i == 0 || items[i] == items[i - 1])? cnt: ++cnt;
        }
    }

    SuffixArray() {}
    SuffixArray(int *s, int l) {
        memcpy(str, s, sizeof(int) * l);
        len = l;
    }

    void CalcSA() {
        for (int i = 0; i < len; i++) {
            rank[i] = str[i] + 88;
        }
        for (int i = 1; i < 2 * len; i *= 2) {
            for (int j = 0; j < len; j++) {
                items[j] = RadixItem(j, rank[j], (j + i < len)? rank[j + i]: -1);
            }
            RadixSort();
        }
        for (int i = 0; i < len; i++) sa[rank[i]] = i;
        // for (int i = 0; i < len; i++) printf("%d ", sa[i]);
    }

    void CalcHeight() {
        int h = 0;
        for (int i = 0; i < len; i++) {
            if (rank[i] == 0) {
                h = 0;
            }
            else {
                int x = sa[rank[i] - 1];
                if (--h < 0) h = 0;
                for (; i + h < len && x + h < len && str[i + h] == str[x + h]; h++);
            }
            height[rank[i]] = h;
        }
        // for (int i = 0; i < len; i++) printf("%d ", height[i]);
    }
} solver;

bool judge(int x) {
    int minv, maxv;
    for (int i = 0; i < n - 1; i++) {
        if (i && solver.height[i] >= x) {
            minv = maxv = solver.sa[i - 1];
            int j;
            for (j = i; j < n - 1 && solver.height[j] >= x; j++) {
                minv = min(solver.sa[j], minv);
                maxv = max(solver.sa[j], maxv);
            }
            if (maxv - minv > x) return true;
            i = --j;
        }
    }
    return false;
}

int main() {
    #ifdef local
        freopen("theme.in", "r", stdin);
        freopen("theme.out", "w", stdout);
    #endif
    while (scanf("%d", &n) && n) {
        for (int i = 0; i < n; i++) scanf("%d", &a[i]);
        for (int i = 0; i < n - 1; i++) b[i] = a[i + 1] - a[i];
        
        solver = SuffixArray(b, n - 1);
        solver.CalcSA();
        solver.CalcHeight();

        int l = 0, r = n - 1;
        while (l < r) {
            int mid = l + ((r - l + 1) >> 1);
            if (judge(mid)) l = mid;
            else r = mid - 1;
        }
        printf("%d\n", (l > 3)? ++l: 0);
        break;
    }
    return 0;
}

Vue2项目实战:vue2-org-tree实现动态组织架构图 本文详细介绍了如何在Vue2项目中使用vue2-org-tree组件实现动态、可交互的组织架构图。内容涵盖从快速安装、基础渲染到核心功能实战,包括水平布局、节点展开折叠、响应式数据绑定、深度自定义节点内容以及事件处理。同时提供了性能优化、样式覆盖等避坑指南,并通过一个完整的企业级Demo展示了如何打造功能丰富的架构图,助力高效开发后台管理系统。 阅读详情

相关推荐

GaN功率放大器设计避坑指南:从仿真到实测的Doherty PA完整流程(基于ADS 2023)

本文详细介绍了基于ADS 2023软件,从理论计算、电路仿真到版图后仿真的GaN Doherty功率放大器完整设计流程。文章聚焦C波段应用,深入剖析了负载调制网络设计、稳定性处理、版图电磁仿真等关键环节中的常见误区与工程折衷,为工程师提供了一套从设计到实测的实战避坑指南。

weixin_29238147的博客 530

【USACO5.1.3】乐曲主题 动态规划

题目描述   我们用N(1 <= N <=5000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,每个数表示钢琴上的一个键。很不幸这种表示旋律的方法忽略了音符的时值,但这项编程任务是关于音高的,与时值无关。   许多作曲家围绕一个重复出现的“主题”来构建乐曲。在我们的乐曲表示法中,“主题”是整个音符序列的一个子序列,它需要...

a15063149271的博客 261

【微信小程序开发与设计】垃圾智能分类小程序

垃圾分类是将来生活可持续发展的必需项。但是很多人由于缺乏垃圾分类知识,或是因为垃圾分类困难,费时费力,所以没有好好贯彻垃圾分类政策,此时设计一款方便于群众进行智能化垃圾识别分类的微信小程序就显得尤为必要。

Markelle_Fultz的博客 8246

P2743 [USACO5.1]乐曲主题Musical Themes

名可铭的题解报告

CM_20030210的博客 265

MS2107 CVBS转USB2.0 音视频采集芯片,支持1080P@30HZ输出

MS2107 是一款视频和音频采集芯片,支持CVBS转USB2.0 ;可以将 CVBS、S-Video 和音频信号通过 USB接口传送到 PC、智能手机和平板电脑上预览或采集。

TEL18967112838的博客 2076

STM32硬件SPI驱动W5500以太网模块全流程(附避坑指南)

本文详细介绍了STM32硬件SPI驱动W5500以太网模块的全流程,包括硬件架构设计、SPI接口选型、官方驱动移植、网络协议栈配置与优化等关键步骤。通过实战案例和性能对比数据,帮助开发者快速实现稳定高效的网络连接,特别提供了常见问题排查指南和性能调优技巧。

weixin_29194693的博客 269

[USACO 5.1.3]Musical Themes(后缀数组)

【题目描述】: 我们用N(1 许多作曲家围绕一个重复出现的“主题”来构建乐曲。在我们的乐曲表示法中,“主题”是整个音符序列的一个子串,它需要满足如下条件:⒈长度至少为5个音符⒉在乐曲中重复出现(可能经过转调,见下)⒊重复出现的同一主题不能有公共部分。“转调”的意思是主题序列中每个音符都被加上或减去了同一个整数值。 给定一段乐曲,计算其中最长主题的长度(即音符数)。【

天空の行者 1294

YOLOv11模型压缩技术全面对比:剪枝、量化、蒸馏的原理与实战

YOLOv11模型压缩技术综述 模型压缩技术是解决计算资源受限环境下部署深度学习模型的关键。本文系统介绍了YOLOv11模型压缩的三种核心技术:剪枝、量化和蒸馏。剪枝技术通过移除冗余参数实现模型轻量化,包括结构化剪枝(通道/卷积核剪枝)和非结构化剪枝;量化技术通过降低数值精度(如FP32→INT8)减少存储和计算量;蒸馏技术则利用教师模型指导学生模型训练,在保持精度的同时减小模型规模。三种技术可单独或组合使用,在工业质检、智慧安防等边缘计算场景中发挥重要作用,使YOLOv11在保持80%精度的同时减少70%

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 579

POJ - 1743 Musical Theme (后缀数组)

题目链接:POJ - 1743(不可重叠最长子串) 题意:有N(1<=N<=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的子串,它需要满足如下条件: 1.长度至少为5个音符。 2.在乐曲中重复出现(就是出现过至少两次)。(可能经过转调,“转调”的意思是主题序列中每个音符都被加上或减去了同一个整数值) 3.重复出现的同一...

只能过样例嘤嘤嘤的博客 250

K8s(十二):监控与报警(163邮箱+钉钉)-Prometheus + Grafana + Alertmanager(超详细)

🔴 K8s(十二):监控与报警(163邮箱+钉钉)-Prometheus + Grafana + Alertmanager(超详细)

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 3万+

Spring Boot 调用豆包大模型如何开启联网搜索?

场景推荐方案有权限创建 Bot + 需强集成✅ 使用bot-xxxx无 Bot 权限 / 追求通用性✅ 自行集成搜索引擎 + 普通豆包模型仅需基础对话❌ 无需考虑联网豆包大模型确实支持联网搜索,但前提是:你用的是“智能体 Bot”,且它被配置了“网页搜索”插件,并调用正确的 API 端点。希望本文能帮你少走弯路,快速构建出真正“知天下事”的智能助手!

lpfasd123的博客 1124

USACO 5.1 Musical Themes(哈希+二分)

Musical ThemesBrian Dean A musical melody is represented as a sequence of N (1 <= N <= 5000) notes that are integers in the range 1..88, each representing a key on the piano. It is unfortu...

weixin_30768661的博客 228

《网络安全自学教程》- SQL注入之报错注入原理+步骤+实战操作

这篇文章为大家解析报错注入的实现原理,结合实战案例讲解报错注入的使用步骤。

wangyuxiang946的博客 1万+

C++——【USACO 5.1.3】——Musical Themes

Musical Themes Brian Dean A musical melody is represented as a sequence of N (1 <= N <= 5000) notes that are integers in the range 1..88, each representing a key on the piano. It is unfortunate bu

McDonnell_Douglas的博客 514

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

USACO5.1.3 Musical Themes (theme)

dp[i][j]表示第一个串匹配到了i,第二个串匹配到了j的最长公共部分的长度。 只不过这题不能直接匹配,要计算后一个和前一个的差值再匹配。 dp[i][j]=max(dp[i][j],dp[i-1][j-1]) (arr[i]-arr[j]==arr[i-1]-arr[j-1]) 因为不能有重复部分,所以当i-dp[i-1][j-1]-1>j时才进行dp。 用滚动数组实现。/* ID:s

Shion的专栏 757

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

usaco training 5.1.3 Musical Themes 题解

【原题】 Musical Themes Brian Dean A musical melody is represented as a sequence of N (1 <= N <= 5000) notes that are integers in the range 1..88, each representing a key on the piano. It is unfort

阿蒋的专栏 2218

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【USACO 5.1.3】Musical Themes

Musical ThemesBrian Dean A musical melody is represented as a sequence of N (1 <= N <= 5000) notes that are integers in the range 1..88, each representing a key on the piano. It is unfortunate ...

weixin_30480651的博客 94

USACO5.1.3 Musical Themes(theme)

寻找最长的重复序列,枚举两个序列的开头的序列的长度 采用了一个力度很大的优化: 每次枚举末端那一位时都从开始的一位加上当前最大长度开始枚举,前一个序列开头只用枚举到(N-当前的最大长度)即可。 /* PROB: theme LANG: C++ ID: xsy97051 */ #include #include using namespace std; int v[5050],an

xsy_victory的专栏 418

【USACO5-1-3】乐曲主题Musical Themes dp

题目#include&lt;iostream&gt; #include&lt;cctype&gt; #include&lt;cstdio&gt; using namespace std; int dp[5050][5050],a[5050]; int n,ans; int read() { char ch=getchar();int ret=0; for (;!isdigit(ch);ch=g...

Mininda 428

Musical Themes (theme)[USACO 5.1.3]

算法:枚举 分析:赤裸裸的枚举啊,数据弱到不行啊~ program theme; const maxn=5000; var n,max:longint; a:array [0..maxn] of longint; procedure init

237

[USACO5.1] Musical Themes

后缀数组求最长重复且不重叠子串。 poj 1743 传送门 洛谷 P2743 传送门 1.子串可以“变调”(即1 3 6和3 5 8视作相同)。解决办法:求字符串相邻元素的差形成新串。用新字符串求解最长重复子串即可。 2.最长重复子串不能重叠。解决办法:用sa数组判断开始位置。 倍增答案即可,从1到n枚举height,记录子串开始的最左端、最右端。 如果找到了两个后缀,其公共前缀长度大...

weixin_30307267的博客 182

Musical Themes [USACO]

用的就是后缀数组。最近非常烦躁。谁人定我去或留,定我心中的宇宙。 /* ID: zhangyc1 LANG: C++ TASK: theme */ #include <string> #include <cstring> #include <cstdlib> #include <cstdio> using namespa...

weixin_30485379的博客 127

[USACO5.1] 乐曲主题Musical Themes题解

(某洛谷)我们用)个音符的序列来表示一首乐曲,每个音符都是范围内的整数,每个数表示钢琴上的一个键。很不幸这种表示旋律的方法忽略了音符的时值,但这项编程任务是关于音高的,与时值无关。许多作曲家围绕一个重复出现的“主题”来构建乐曲。在我们的乐曲表示法中,“主题”是整个音符序列的一个子串,它需要满足如下条件:1. 长度至少为个音符。2. 在乐曲中重复出现(可能经过转调,见下)。3. 重复出现的同一主题不能有公共部分。“转调”的意思是主题序列中每个音符都被加上或减去了同一个整数值。

ericjian2011的博客 479

Luogu P2743 [USACO5.1]乐曲主题Musical Themes

链接 \(Click\) \(Here\) 人生第一道后缀数组的题目。首先要对输入的串进行差分处理,差分后长度为(\(n - 1\))的相同子段就是原串中长度为\(n\)的相同(可变调)子段。求出来\(height\)以后,二分一个最大不相交重复子段长度,在\(can\_use\)里面维护长度为\(k\)的段划分,判断不相交只要用\(sa\)的差值算一下长度就好。 \(p.s.\)细节真的很多。 ...

weixin_33912638的博客 119

Usaco Training Section 5.1 Musical Themes

一长串数(&lt;=5000个),若一段数和另一段数长度相同,且对应数的差相同,则算同一种。问最长的出现不止一次的序列的长度是多少。 法一(乱搞): 最直接的想法是枚举。我先把相邻两数的差存了下来,然后枚举了起始点,又枚举了与它相同的所有点,然后一位一位往后比对,这复杂度有点问题,但我判了一下如果循环次数超过一个值,就跳出,神奇地a了!!! #include&lt;bits/stdc+...

Monster的博客 273

USACO 5.1 Musical Themes(KMP,二分 / 暴力)

2015-03-2921:52:30 思路:这题... 一开始用KMP暴力超时掉了... 套了个二分就过了。。 看比人貌似用暴力也可以过?。   二分枚举长度,可以证明若重复的theme长度L可行,那么l < L的也可行,符合单调性。   根据枚举的长度来枚举起点然后KMP即可。 1 /* 2 ID:naturec1 3 PROG: theme 4 LA...

dingdi3021的博客 143
上一篇: usaco5.1.2 Starry Night
下一篇: usaco5.3.1 Milk Measuring
max_kibble
博客等级 码龄11年 2粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值