合唱(8)

1 题目

(此题来源牛客网网易2018秋招笔试真题)

1.1 题目描述

小Q和牛博士合唱一首歌曲,这首歌曲由n个音调组成,每个音调由一个正整数表示。

对于每个音调要么由小Q演唱要么由牛博士演唱,对于一系列音调演唱的难度等于所有相邻音调变化幅度之和, 例如一个音调序列是8, 8, 13, 12, 那么它的难度等于|8 - 8| + |13 - 8| + |12 - 13| = 6(其中||表示绝对值)。
现在要对把这n个音调分配给小Q或牛博士,让他们演唱的难度之和最小,请你算算最小的难度和是多少。

如样例所示: 小Q选择演唱{5, 6}难度为1, 牛博士选择演唱{1, 2, 1}难度为2,难度之和为3,这一个是最小难度和的方案了。

1.2 输入描述

输入包括两行,第一行只有一个正整数n(1 <= n <= 2000),第二行n个正整数v[i](1 <= v[i] <= 10^6),表示每个音调。

1.3 输出描述

输出一个整数,表示难度之和最小为多少。

1.4 输入示例

5

1 5 6 2 1

1.5 输出示例

3     //1 2 1一个人唱,5 6另一个人唱

2 问题分析

把问题直接翻译过来,就是给一个数组,将其分成两个数组(不能改变原有次序),使得这两个数组的各自元素之差的绝对值的和最小。

采用动态规划解题:

用一个二维数组,d[i,j]表示前i个音符中,有个人最后一次唱的时第j个音符,从j+1到i全是由另一个人唱的,对应的难度之和。外层循环用i表示,从第1个音符一直到最后一个音符,内层循环用j表示,表示其中有个人最后唱的一个音符时j。

当循环开始时候,即是否更新d[i,j]时候,考虑两种情况:1)唱最后一个音符时候换人,2)不换人。

3 代码编写

//还没有做完
#include <iostream>
#include <algorithm>
using namespace std;

void test(){
    int n;        //一共有n个音符
    cin>>n;
    
    int* v = new int[n+1];      //音符数组
    for(int i = 1;i <= n;i++)
        cin>>v[i];
    v[0] = v[1];                //把第0个也初始化了

    int** d = new int*[n+1];    //初始化二维数组
    for(int i = 0;i <= n;i++)
        d[i] = new int[n+1];
    for(int i = 0;i <= n;i++)
        for(int j = 0;j <= n;j++)
            d[i][j] = 0;

    for(int i = 1;i <= n;i++){
        arr[i] = arr[i-1] + abs(v[i] - v[i-1]);
        for(int j = 0;j < i;j++){
            d[i][j] = d[i-1,j] + abs(v[i] - v[i-1]);
        }
        int t1;
        for(int k = 0;k <= i-1;k++){
            int t2 = d[i-1][k] + 
        
}

int main()
{
    test();
    return 0;
}

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值