C++ 贪心算法错误使用c++;设置

C++ 贪心算法错误使用c++;设置,c++,algorithm,set,greedy,C++,Algorithm,Set,Greedy,我创建了一个贪婪算法来解决一个问题(家庭作业),因为我正在学习c++,所以我想用set实现同样的目标 基本上,我们把作业交给一个在线平台,这个平台作为一些我们不知道的测试用例,我们根据这个平台得到分数。如果我们通过了所有的测试用例,我们有100% 问题是这样的 我们有一位演员,他想和粉丝预约,并回答了一份关于他的在线问卷。现在,他想选择能够最大化问卷中分数总和并尊重风扇可用性的风扇。他一天只能看到一个球迷 我们有这样一个输入: 6 1 1 5 2 2 4 3 1 2 4 3 1 5 1 6

我创建了一个贪婪算法来解决一个问题(家庭作业),因为我正在学习
c++
,所以我想用
set
实现同样的目标

基本上,我们把作业交给一个在线平台,这个平台作为一些我们不知道的测试用例,我们根据这个平台得到分数。如果我们通过了所有的测试用例,我们有100%

问题是这样的

我们有一位演员,他想和粉丝预约,并回答了一份关于他的在线问卷。现在,他想选择能够最大化问卷中分数总和并尊重风扇可用性的风扇。他一天只能看到一个球迷

我们有这样一个输入:

6
1 1 5  
2 2 4
3 1 2
4 3 1
5 1 6
6 2 2
其中第一行是风扇数量,接下来,在每一行中,我们有风扇id、风扇可用天数和在线问卷中获得的风扇点数。我必须打印演员将看到的粉丝ID和粉丝的积分总和。因此,对于上述输入,我有以下输出:

2
4
5
11
请注意,如果两个风扇具有相同的点,则首选的风扇应为ID较低的风扇

我首先按照问卷的分数(降序)和较低的id对粉丝进行排序。 在读取输入时,我将天数添加到
集合
。 我的想法是这样的:

6
1 1 5  
2 2 4
3 1 2
4 3 1
5 1 6
6 2 2
在迭代数据时,我检查可用的扇入研究天数是否在
集合中。如果是,请添加此风扇并从集合中删除天数。如果风扇天数不在集合中,则获取
上限
,并减少迭代器以将第一天的风扇设置为比第一天低。如果集合是空的,或者我迭代了所有的风扇,算法就会停止

这是我的贪婪函数:

void greedy() {
    fan_id.insert(questionnaire_result[0][0]);
    days_available.erase(questionnaire_result[0][1]);
    total_questionaire_sum += questionnaire_result[0][2];

    int i;
    for (i = 1; i < number_of_fans; i++) {
        if (days_available.empty()) {
            break;
        } else if (days_available.count(questionnaire_result[i][1])) {
            fan_id.insert(questionnaire_result[i][0]);
            days_available.erase(questionnaire_result[i][1]);
            total_questionaire_sum += questionnaire_result[i][2];
        } else {
            it = days_available.upper_bound(questionnaire_result[i][1]);
            if (it == days_available.begin()) {
                if (*it < questionnaire_result[i][1]) {
                    fan_id.insert(questionnaire_result[i][0]);
                    days_available.erase(*it);
                    total_questionaire_sum += questionnaire_result[i][2];
                }
            } else if (it == days_available.end()) {
                it--;
                if (*it < questionnaire_result[i][1]) {
                    fan_id.insert(questionnaire_result[i][0]);
                    days_available.erase(*it);
                    total_questionaire_sum += questionnaire_result[i][2];
                }

            } else {
                it--;
                if (*it < questionnaire_result[i][1]) {
                    fan_id.insert(questionnaire_result[i][0]);
                    days_available.erase(*it);
                    total_questionaire_sum += questionnaire_result[i][2];
                }
            }
        }
    }
}
我已经测试了许多可能性,这在我所有的测试用例中都起作用。不幸的是,我们没有平台的测试用例

有人看到我的代码失败的情况吗?有了这个,我得到了90%的分数

编辑:

正如Edward指出的,我成功地解决了这样的问题:

6
1 1 5  
2 2 4
3 1 2
4 3 1
5 1 6
6 2 2
读取输入时添加了这行代码:

max_days = max_days | questionnaire_result[i][1];
然后做了这个:

for (int j = 1; j < max_days + 1; j++) {
            days_available.insert(j);
        }
for(int j=1;j

问题已解决

此输入文件将导致程序生成不正确的结果:

2
1 2 6
2 2 5

这两个风扇都可以使用,所以很明显,两个风扇都可以访问,总输出分数应该是11。但是,您的算法只选择第一个,并输出6分。

不是答案,而是在
else if(it==days\u available.end())
else
分支相同,因此
else if
分支可以删除。是的。你说得对。它给了我完全相同的分数输出中的球迷应该按id排序,还是按他们的约会排序?因为我想最大化分数,应该按问题中的分数排序。输出的重新排序不会改变分数的数量。我的问题是在线平台接受什么作为有效输出。在您的示例中,它是否接受
2 4 5 11
(按id排序)或
5 2 4 11
(按约会排序)?非常感谢。以你为例,我明白我做错了什么,现在终于解决了问题。编辑我的问题以包含解决方案。再次感谢