这个程序的复杂度是什么?

4

我在HackerEarth上解决了一个问题。

问题是:Phineas正在他的后院建造一座城堡以打动Isabella(很奇怪,不是吗?)。他已经把所有东西都送来了并准备好了。连地面层都已经完成了。现在是时候制作上部分了。这就是事情变得有趣的地方。由于Ferb在长时间刷栅栏后睡觉了(而你们帮了他, 不是吗!), Phineas必须自己做所有的工作。他擅长这个,他想让你操作迷你起重机来吊起石头。墙上的石头已经被切割好并准备好等待你把它们吊起来。

现在我们没有Ferb来操作迷你起重机,他是一个专家,我们必须尽快完成工作。我们知道了起重机的最大承载能力和每块石头的重量。由于这是一个迷你起重机,我们不能一次放置超过2个石头(任何可能的大小),否则它会影响到起重机的平衡。我们需要找出在多少轮中我们可以把石头交给正在建造城堡的Phineas。

输入: 输入的第一行给出T,表示测试用例的数量。对于每个测试用例,第一行给出M,表示起重机的最大承载能力。接下来每个测试用例的下一行的第一个整数N表示石头的数量,后面跟着N个数字,指定了每块石头X的重量。

输出: 对于每个测试用例,输出操作起重机的最小轮数,以便吊起所有的石头。

约束:

1 <= T <= 50
1 <= M <= 1000
1 <= N <= 1000

示例输入

1
50
3 28 22 48

样例输出

2

解释

首先,28和22将一起被举起。其次,将48举起。

丢弃重量大于起重机最大承载能力的石头。

现在我已经解决了这个问题,我的源代码如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
using namespace std;


int main(void) {
    int T = 0;
    scanf("%d",&T);
    while(T--) {
        int i = 0,M = 0, N = 0,max = 0, res = 0, index = 0, j = 0, temp = 0;
        vector<int> v1;
        scanf("%d",&M);
        scanf("%d",&N);
        for(i = 0; i < N ;++i) {
            scanf("%d",&temp);
            if(temp <= M)
                v1.push_back(temp);
        }

        for(i = 0; i < v1.size() ; ++i) {
            max = 0;
            index = 0;
            if(v1[i] != -1) {
                for(j = i + 1; j < v1.size(); ++j) {
                    if(v1[j] != -1) {
                        temp = v1[i] + v1[j];
                        if(temp > max && temp <= M) {
                            max = temp;
                            index = j;
                        }
                    }
                }
                ++res;
                v1[i] = -1;
                v1[index] = -1;
            }
        }

        printf("%d\n",res);
    }

    return 0;

}

现在这里有我的问题

  1. 我想知道这段代码的平均时间复杂度。此外,我认为这段代码的最坏情况复杂度将是O(N^2)。
  2. 这是一种暴力方法还是动态规划方法?
  3. 有没有比这更好的方法?

4
我正在投票关闭这个问题,因为它不属于此处讨论的范畴,应该发表在代码审查板块。 - Walter
1
@Walter,我认为你没有理解这种问题的重点。这是一道OI/ACM类型的竞赛题目,而不是生产环境中的问题。OP只是想要一个更好的解决方案,并对他自己的尝试进行评论。 - miushock
@miushock 那就属于[codereview.se]了。 - sashoalm
1
@sashoalm 这部分涉及到代码本身,但更多的是关于如何解决这个竞赛编程问题。如果这属于代码审查,那么像算法和动态规划这样的 SO 标签是用来做什么的呢? - miushock
3
“是否有更好的方法”这个问题显然属于代码审查领域,但解释我的写法部分则不太是。现有的答案并不完全是一次代码审查,因此该问题不再适合迁移。geeksoul欢迎在Code Review上进行交叉发布-只要你在问题中声明即可。 - 200_success
1个回答

3
这是背包问题的简化版本。
虽然背包问题是一个典型的动态规划问题,但这个简化版问题不需要使用动态规划。虽然你的解决方案复杂度确实为O(n^2),但是这种方法更适合描述为贪心算法。因为你试图找到每个石头的最优组合(如果存在)。如果你先将石头排序并在排序后的向量上工作,复杂度可以进一步降低到O(nlgn)。

虽然大家都在争论这个问题是否属于离题,但我有一个问题。这个问题能否用DP实现?(是或否)我不知道为什么有些人评论说这个问题是离题的?我没有要求别人审查我的代码并给我评分吗?我只是询问了一下我的代码复杂度?我尊重你们的观点,如果你们中的一些人同意,那么我会删除这个问题,但我认为这个问题对其他正在学习DP并且仍然困惑于他们的代码是否属于DP的人也可能有用。谢谢你们的时间。 - Deepanshu
其中三个属于代码审查,但有两个不属于,而且2 > 1,所以我在这里发布了。同时在另一个网站(code-review stackoverflow)上发布同样的问题只是浪费资源和时间。 - Deepanshu
@geeksoul 我不太明白你是如何理解DP的,但既然问题本身并没有要求或者你的代码也没有反映出计算最优子结构的选择,所以我不认为这是一个DP问题。我建议你阅读一下背包问题的维基,并尝试自己实现它,之后你就不再需要问别人这个问题了。 - miushock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接