• 在set中放入自定义类型


    这件事情的起因是在学习背包问题时突然想到了一种算法,分析了一下应该是n^2logn复杂度的,当然比dp慢。但是既然想到了就实现了下:

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ll;
    /*一个很低效的方法,但是是自己想到的,就顺手实现了一下。本质是基于穷举法的优化,不再循环所有物品选取的组合,而是循环状态。
    大致地看,其一定是比穷举法要快些的,因为其合并了穷举法的许多情况,即处于“现在背包中物品的总价值相同且剩余空间相同”的不同物品选取情况。
    但是其的复杂度至少是n^2*logn级别的,因为其需要对每一个物品循环set中的元素并不断插入新的状态,而且还涉及到了类的存储,速度应该会更慢一些 */
    class stateNow{
    public:
        int sizeRest;
        int valueAll;
        bool operator <(const stateNow& te)const{
            if((this->sizeRest<te.sizeRest)||(this->sizeRest==te.sizeRest&&this->valueAll>te.valueAll))
            return true;
            else 
            return false;
        }
    };
    int main(){
    int n,size;
    scanf("%d %d",&n,&size);
    int *objectSize=new int[n];
    int *objectValue=new int[n];
    set<stateNow>::iterator it;
    set<stateNow>stateCollection;
    int maxValue=0;
    for(int i=0;i<n;i++){
        scanf("%d %d",&objectSize[i],&objectValue[i]);//不能把
    也加到字符串里,
    是输入结束的标志,将它也读入的话会影响结束
    }
    for(int i=0;i<n;i++){
            if(!stateCollection.empty()){
            for(it=stateCollection.begin();it!=stateCollection.end();it++){
            stateNow temp;
            temp.sizeRest=it->sizeRest-objectSize[i];
            temp.valueAll=objectValue[i]+it->valueAll; 
            if(temp.sizeRest==0){
                if(temp.valueAll>maxValue)
                maxValue=temp.valueAll;
            }
            if(temp.sizeRest>0)
                stateCollection.insert(temp);
            }
            }
            stateNow temp;
            temp.sizeRest=size-objectSize[i];
            temp.valueAll=objectValue[i]; 
            stateCollection.insert(temp);
    }
    printf("%d",maxValue);
    getchar();
    }
    }

    这里就涉及到了一个向set中传入自定义类型的问题,查到了一篇博文,正好在讲这个问题,这里就不引用原文了,大家直接点击链接看吧:https://www.cnblogs.com/shawnhue/archive/2011/12/22/set_comparison_strick_weak_ordering.html

    为什么需要定义比较函数对象或者自定义<运算符呢?因为set内部是有序排列的(红黑树),并且要保证元素的唯一性,所以需要一个能用来比较两元素的方法。(two keys k1 and k2 are considered to be equivalent if for the comparison object comp, comp(k1, k2) == false && comp(k2, k1) == false.

    另外,由博文中所说,总是让比较函数使被比较对象满足严格的弱序,即

    严格弱序化拥有如下属性。对于集合S中所有的x,y,z,

    对于所有的x,不存在x < x (非自反性 - 21条标题说的就是这个)

    对于所有x不等于y,如果x < y那么不存在y < x (不对称性)

    对于所有的x,y和z,如果x < y并且y < z,那么x < z(传递性)

    如果x < y,那么对于所有的z,要么x < z要么z < y(或者两者都成立)

    这一点在自定义<运算符时要注意,否则所进行的操作就是未定义行为,会出现意料之外的错误。

  • 相关阅读:
    在VS2010 C++中调试DLL工程的方法
    Dos命令关机、重启
    js中实现缓动效果
    win32程序窗口的创建
    win32子窗口和控件
    c++DLL添加导出函数
    Win32创建窗口的过程
    贝塞尔曲线的数学原理
    一些基本的GDI操作BITMAP的方法
    Windows快捷键
  • 原文地址:https://www.cnblogs.com/jiading/p/11108821.html
Copyright © 2020-2023  润新知