ACM之近期学习总结

博主分享了在ACM学习过程中的区间dp理解和应用,通过两道具体题目阐述了区间dp的解决思路,强调了多做题和理解题目的重要性。此外,还总结了构造函数的初始化列表、const成员函数等C++编程知识。
摘要由CSDN通过智能技术生成

一.区间dp

感想:最近做的区间dp的题实在太少啦,因为对这一方面的dp题我只是对最基础的题型有了解,但对于比较复杂的区间dp首先我的思路比较受限,看到一个题后无法将它由一个大区间划分为小区间,并找出状态转移方程。对于老师给出的csdn的链接我也看了一部分,但有些题看了代码对于思路的想法也还是一知半解,没有理解到区间dp的实质,导致换一道题即使本质相似,也还是想不出思路和代码,所以还是要多见题,多了解别人做题的思路,并归纳总结出一类题的相同之处,再自己做题打代码。

1.

题意:在x轴上有n个客人,每个客人每秒增加的愤怒值不同。给出客人和餐厅的位置,以及客人每分钟增加的愤怒值,和送餐行走一公里需要的时间,问送完n个客人的外卖最小愤怒值

思路

把餐厅所在的点加进去,然后按照在x轴上的位置排序。从餐厅所在位置向左右开始DP

dp[i][j][0]表示从i到j用户送到最小不开心值,此时送货员停留在左边即i位置

dp[i][j][1]表示从i到j用户送到最小不开心值,此时送货员停留在右边即j位置

状态有四种,

            dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][0] + (a[i+1].x-a[i].x)*(sum[n]-sum[j]+sum[i]));
            dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][1] + (a[j].x-a[i].x)*(sum[n]-sum[j]+sum[i]));
            dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][0] + (a[j].x-a[i].x)*(sum[n]-sum[j-1]+sum[i-1]));
            dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][1] + (a[j].x-a[j-1].x)*(sum[n]-sum[j-1]+sum[i-1]));

2.

题意:有一群屌丝,每个屌丝有个屌丝值,如果他第K个上场,屌丝值就为Diaosi[i]*(k-1),通过一个小黑屋来调整,使最后总屌丝值最小。

思路:设dp[i][j]表示从第i个人到第j个人这段区间的最小花费(是只考虑这j-i+1个人,不需要考虑前面有多少人)

那么对于dp[i][j]的第i个人,就有可能第1个上场,也可以第j-i+1个上场。考虑第K个上场

即在i+1之后的K-1个人是率先上场的,那么就出现了一个子问题 dp[i+1][i+k-1]表示在第i个人之前上场的

对于第i个人,由于是第k个上场的,那么屌丝值便是a[i]*(k-1)

其余的人是排在第k+1个之后出场的,也就是一个子问题dp[i+k][j],对于这个区间的人,由于排在第k+1个之后,所以整体愤怒值要加上k*(sum[j]-sum[i+k-1])

 

二.闲碎知识点总结

1.构造函数重载

构造函数是可以重载的,即可以写多个构造函数,它们的参数表不同。当编译到能生成对象的语句时,编译器会根据这条语句所提供的参数信息决定该调用哪个构造函数。如果没有提供参数信息,编译器就认为应该调用无参构造函数。

class Complex{
    private:
        double real, imag;
    public:
        Complex(double r);
        Complex(double r, double i);
        Complex(Complex cl, Complex c2);
    };
    Complex::Complex(double r)  //构造函数 1
    {
        real = r;
        imag = 0;
    }
    Complex :: Complex(double r, double i)  //构造数 2
    {
        real = r;
        imag = i;
    }
    Complex :: Complex(Complex cl, Complex c2)  //构造函数 3
    {
        real = cl.real + c2.real;
        imag = cl.imag + c2.imag;
    }
    int main(){
        Complex cl(3), c2(1,2), c3(cl,c2), c4 = 7;
        return 0;
    }



根据参数个数和类型要匹配的原则,c1、c2、c3、c4 分别用构造函数 1、构造函数 2、构造函数 3 和构造函数 4 进行初始化。初始化的结果是:c1.real = 3,c1.imag = 0 (不妨表示为 c1 = {3, 0}),c2 = {1, 2},c3 = {4, 2}, c4 = {7, 0}。

2.构造函数初始化列表

初始化列表位于构造函数的参数表之后,函数体之前:

    构造函数(参数表):初始化列表{函数体}

class Student
{
     private:   
           int m_num,m_maths ;
     public:
         Student(){}//默认构造函数
          Student(int num,int maths  ):m_num(num),m_maths(maths)
          {
              
             cout<<m_num<<endl;
             cout<<m_maths<<endl;
         }
 
};

3.const用法

(1)定义常量  : 可以为所有的内置类型对象使用const限定符,可以用const代替#define来定义常量

const int buf=100;

(2)const限定指针的两种用法:(1)限定指针指向的对象  (2)限定指针中存放的内容

const修饰指针变量时:

  (1)只有一个const,如果const位于*左侧,表示指针所指数据是常量,不能通过解引用修改该数据;指针本身是变量,可以指向其他的内存单元。

  (2)只有一个const,如果const位于*右侧,表示指针本身是常量,不能指向其他内存地址;指针所指的数据可以通过解引用修改。

  (3)两个const,*左右各一个,表示指针和指针所指数据都不能修改。

const int*pl;   //P1是一个指向const int的指针,指向常量对象
int const*pl;   //效果同上
int d=l;
int* const p2=&d;  //P2是一个指向int的指针常量,一直指向d
const int* const p3=&d;  //指针与其指向的对象都是常量

 3. 限定函数参数(const修饰符也可以修饰函数的传递参数)

void Fun(const int Var);    //告诉编译器Var在函数体中的无法改变.

 4.限定函数返回值(const修饰符也可以修饰函数的返回值,是返回值不可被改变)

const int Fun1(); const MyClass Fun2();

 5.限定对象

限定的对象不能被修改,不能调用非成员函数。

 6. 限定数据成员

限定的数据成员在创建对象时初始化,之后值不能修改。

 7.限定成员函数

限定的成员函数不会修改数据成员的值,可以被const对象调用,也可以被非const对象调用。

 

定义const成员函数的语法形式为

返回类型 成员函数名(参数表) const {函数体}

class X{
     int m;
   public:
     X(int v=0):m(v){}
     void set(int v){m=v;}
     int get() const {return m;}
};
...
const X b(5);  //const 对象
b.get();   //正确
b.srt(10);   //错误

  const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值