其他分享
首页 > 其他分享> > [正经向] 九月杂题整理

[正经向] 九月杂题整理

作者:互联网

挺新颖的DP虽然是很早的题了

设计状态\(f_{i,v,k}\)表示考虑前\(i\)个物品,现在装了\(v\),排名\(k\)的解。我们考虑这个解一定是可以从\(f_{i-1,v,1\to K}\)或者\(f_{i-1,v-cost_i,1\to K}+val_i\)转移过来的,并且随着\(k\)递增,\(f\)递减,所以转移的时候就可以从两个状态集各拉一个指针过来,单调转移一下即可。

    for (i = 0 ; i < M ; ++ i)
            for (j = 1 ; j <= K ; ++ j)
                    f[i][j] = - Inf ; f[0][1] = 0 ; 
    for (i = 1 ; i <= N ; ++ i)
            for (j = M ; j >= c[i] ; -- j){
                    int H1 = 0, H2 = 0 ;  
                    if (f[j - c[i]][1] < 0) continue ; 
                    tmp[1] = f[j][1] ; 
                    for (k = 1 ; k <= K ; ++ k, tmp[k] = f[j][k]){
                            if (f[j - c[i]][H1 + 1] + v[i] > tmp[H2 + 1]) 
                                H1 ++, f[j][k] = max(f[j][k], f[j - c[i]][H1] + v[i]) ;
                             else H2 ++, f[j][k] = max(f[j][k], tmp[H2]) ; 
                        }
                }
    for (i = 1 ; i <= K ; ++ i) ans += f[M][i] ;

以前写过详细的:Link

很简单的线段树,就是“所\(maintain\)非所\(query\)”这个技巧还是可以学一下的。简单记一下比较妙的\(query\)函数吧:

int query(int rt, int l, int r){
    down(rt) ; 
    if (l == r) return l ; 
    int ls = rt << 1, rs = rt << 1 | 1, mid = (l + r) >> 1 ; 
    if (T[ls].S >= O) return query(ls, l, mid) ; 
    else if (T[ls].Rs + T[rs].Ls >= O) return mid - T[ls].Rs + 1 ; 
    return query(rs, mid + 1, r) ; 
}

\(f_{l,r}\)表示只剩\([l,r]\)之间没取的最大值,\(n^2\)之后统计每个\(f_{i,i}\)算贡献,挺水的一dp。

标签:正经,int,return,H2,ls,rm,query,杂题,九月
来源: https://www.cnblogs.com/pks-t/p/11748728.html