我在HackerEarth上解决了一个问题.
问题是
菲尼亚斯正在他的后院建造一座城堡,以给伊莎贝拉留下深刻印象(奇怪,不是吗?).他已经准备好了所有的东西.一楼即使已经完工.现在是时候做出上半部分了.这是事情变得有趣的地方.经过漫长的一天画围栏后,Ferb正在房子里睡觉(你们大家帮助了他,不是吗!),Phineas必须自己做所有的工作.他很擅长这一点,他想要你做的就是操作小型起重机来抬起石头.墙上的石头已被切断,准备好等你抬起它们.
现在我们没有Ferb来操作他是专家的小型起重机,我们尽可能快地完成这项工作.我们获得了起重机的最大起重能力和每块石头的重量.由于它是一台小型起重机,我们一次不能放置2块以上(任何可能尺寸)的石块,否则会扰乱起重机的平衡.我们需要知道我们可以将多少转弯交给正在建造城堡的菲尼亚斯.
INPUT:输入的第一行给出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;
}
现在这是我的问题
>我想知道此代码的平均时间复杂度.此外,我认为此代码的最坏情况复杂性为O(N ^ 2).
>这是一种蛮力方法还是动态编程方法?
>那么这有什么更好的方法吗?
最佳答案 这是
Knapsack Prolblem的简化版本
虽然背包问题是典型的动态编程问题,但这个简化的问题不需要动态编程.你的解决方案的复杂性确实是O(n ^ 2),这种方法更适合描述为Greedy当你试图找到每块石头的最佳对时,如果存在的话.如果您先对石头进行排序并处理已排序的矢量,则复杂性可以进一步降低到O(nlgn).