4.10考试(过程)

上来看到problem1,想到了之前比赛做过的“游戏”问题,这两个题何其相似。

第一时间想考虑贪心,推了一会儿,发现这个题的不适用贪心策略(即使可能有这样的策略,判断也过于复杂)

不贪了,搜索

写到一半,想了想一些特殊判断剪枝,n与k均为正数,k小于n的情况下方法没得选,只能不断-1,于是把它加在前面了:

if(k<n) printf("%d\n",n-k),exit(0);

写搜索的时候也卡了一会,因为一开始想用一个变量ans记录,不现实啊!应该用数组记录到达某个点的步数。

problem2:单调序列,先找了找几个特点:

第一,不上升和不下降两个都要考虑;

第二,目标未知;

第三,要求最小改变量,而不是最小改变次数。

由第三点就知道肯定要动态规划来做,但是目标未知!

所以思考了一下,最优策略下改变结果一定都是原序列有的数

比如1 3 2 4 5 3 9 -->1 3 3 4 5 5 9,其中设b[]={1,2,3,4,5,9}作为目标数组。

然后就要考虑怎么dp了,这段最费时间,不过好在能够解决第一点(不上升和不下降,改变dp顺序即可)

然后开始写,中间还是要注意初始化。

int dp(){
    memset(f,0x5f,sizeof(f));
    memset(f[0],0,sizeof(f[0]));
    FOR(i,1,n){
        FOR(j,0,m){
            f[i][j] = min(f[i][j-1],f[i-1][j]+abs(a[i]-b[j]));
        }
    }
    int ans = f[n][m]; //正反搜两次 
    memset(f,0x5f,sizeof(f));
    FOR(i,1,n){
        ROF(j,m,0){
            f[i][j] = min(f[i][j-1],f[i-1][j]+abs(a[i]-b[j]));
        }
    }
    ans = min(ans,f[n][m]);
    return ans;
}

problem3,一眼看出来是树状数组/线段树问题。

(大样例的亿点问题好像对我没影响,能正常输出不知为什么)

两个操作是区间修改+区间查询?(这个超出我能力范围,但是勉强写了个单点查询+循环,可能超时)

先写了前面的树状数组一些基本函数(忘得差不多了)

然后才想起来要用b[i]=a[i]-a[i-1]来构成数组。

判断大于c的部分,卡了40分钟左右,后面就写暴力提交了。

 

posted @ 2022-04-10 11:30  yinfelix  阅读(29)  评论(0)    收藏  举报