最优合并问题-ACM

你看我打不打你
本文链接: https://blog.csdn.net/KO812605128/article/details/102483064

最优合并问题
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
给定k 个排好序的序列s1 , s2,……, sk , 用2 路合并算法将这k 个序列合并成一个序列。假设所采用的2 路合并算法合并2 个长度分别为m和n的序列需要m + n -1次比较。试设计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。
为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。
对于给定的k个待合并序列,计算最多比较次数和最少比较次数合并方案。

Input
输入数据的第一行有1 个正整数k(k≤1000),表示有k个待合并序列。接下来的1 行中,有k个正整数,表示k个待合并序列的长度。
Output
输出两个整数,中间用空格隔开,表示计算出的最多比较次数和最少比较次数。
Sample Input

4
5 12 11 2

Sample Output
78 52

这个题的主要思路就是排序、求和、排序、求和......
只不过不要忘记加上每一次求和的结果。
例求最小的时候,其实2+5 被加了多次。
min :2 5 11 12
(2 + 5 - 1) + ((2 + 5) + 11 - 1) + (12 + ((2 + 5) + 11) - 1) = 52
max : 12 11 5 2
(12 + 11 - 1) + ((12 + 11) + 5 - 1) + (2 + ((12 + 11) + 5) - 1) = 78 
#include<bits/stdc++.h>

using namespace std;

int a[1001], b[1010];

int n, m;
bool cmp(int x, int y)
{
    return x > y;
}

int getmax(int *s)
{
    int n = m;
    int sum = 0;
    while(n > 1)
    {
        sort(s, s + n, cmp);
        s[0] = s[0] + s[1];
        sum += s[0] - 1;
        n--;
        for(int i = 1; i < n; i++)
            s[i] = s[i + 1];
    }
    return sum;
}
int getmin(int *s)
{
    int n = m;
    int sum = 0;

    while(n > 1)
    {
        sort(s, s + n);
        s[0] = s[0] + s[1];
        sum += s[0] - 1;
        n--;
        for(int i = 1; i < n; i++)
            s[i] = s[i + 1];
    }
    return sum;
}
int main()
{
    cin>>m;
    for(int i = 0; i < m; i++)
    {
        cin>>a[i];
        b[i] = a[i];
    }
    cout<<getmax(a)<<" "<<getmin(b)<<endl;

    return 0;
}

感觉上面的两个求最大最小可以合并,但是无论怎么改都不能AC,样例啥的都也过了,不知道哪里出错。下面就是自己改的,

终于知道哪里出错了, 每一次计算完一次都要重新排序,所以下面的代码是错误的,结果对只是巧合吧

#include<bits/stdc++.h>

using namespace std;

int n, m;
int a[1010], s[1010];

bool cmp(int x, int y)
{
    return x > y;
}
int display(int *a)
{
    int sum = 0, num = n;
    while(num > 1)
    {
        a[0] = a[0] + a[1];
        sum += a[0] - 1;
        num--;
        for(int i = 1; i < num; i++)
            a[i] = a[i + 1];
    }
    return sum;
}
int main()
{
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        cin>>a[i];
        s[i] = a[i];
    }
    sort(s, s + n);///排序要在每一次最开始进行一次
    sort(a, a + n, cmp);
    printf("%d %d\n", display(a),display(s));

    return 0;
}

最终代码

#include<bits/stdc++.h>

using namespace std;

int a[1001], b[1010];

int n, m;
bool cmp(int x, int y)
{
    return x > y;
}

int main()
{
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        cin>>a[i];
        b[i] = a[i];
    }
    int maxsum = 0, minsum = 0;
    while(n > 1)
    {
        sort(a, a + n);
        sort(b, b + n, cmp);
        m = n;
        a[0] = a[0] + a[1];
        minsum += a[0] - 1;
        n--;///长度减一
        for(int i = 1; i < n; i++)///a[0]不动,原a[1]以后的都向前一位覆盖
            a[i] = a[i + 1];///所有的数前移一位
        b[0] = b[0] + b[1];
        maxsum += b[0] - 1;
        m--;
        for(int i = 1; i < m; i++)
            b[i] = b[i + 1];
    }
    cout<<maxsum<<" "<<minsum<<endl;
    return 0;
}


/***************************************************
User name: 
Result: Accepted
Take time: 32ms
Take Memory: 248KB
Submit time: 2019-10-13 13:02:33
****************************************************/

猜你喜欢

转载自blog.csdn.net/KO812605128/article/details/102483064