GYM 102059 G Fascination Street

G Fascination Street

参考
给出一串n(2e5)个灯, 每个灯点亮可以照到相邻三个位置, 每个灯点亮都有不同的花费, 现在可以交换k(9)次灯的位置, 求把所有n个位置都照到的最小花费.
交换的肯定是一个亮的灯和一个灭的灯, 不然是没有意义的.(即, 将一个花费低的灯点亮, 根花费高, 未点亮的灯交换位置.)
对于每个位置i, 保存最后两个灯(i-1,i)是否点亮(注意是点亮, 不是被照到), 并保存当前有多少个点亮的灯被交换走, 多少个未点亮的灯被交换进来.
那么只会有4种转移方式:
点亮 花了钱, 灯到账
未点亮 没花钱, 不点亮
点亮被换走(对于这个位置相当于没电亮(因为换过来的是没点亮的)) 花了钱, 跑了
没点亮换过来一个(白piao) 没花钱, 到了

int n, k;
ll w[M];
ll dp[M][2][2][10][10];
//    i  a  b  x   y
// 到i位置, i-1位置是a状态, i位置是b状态, 换走了a个点亮的, 换来了b个不亮的

void init() {
    n = read(), k = read();
    for (int i = 1; i <= n; i++)w[i] = read();
    memset(dp, 0x3f, sizeof(dp));
    dp[0][1][0][0][0] = 0;
    for (int i = 0; i < n; ++i) {
        for (int x = 0; x <= 1; ++x) {
            for (int y = 0; y <= 1; ++y) {
                for (int a = 0; a <= k; a++) {
                    for (int b = 0; b <= k; ++b) {//点亮i+1
                        checkMin(dp[i + 1][y][1][a][b], dp[i][x][y][a][b] + w[i + 1]);
                        if (x || y)//不点亮i+1 不能有000
                            checkMin(dp[i + 1][y][0][a][b], dp[i][x][y][a][b]);
                        if (b < k)//别地方拿一个点亮的放在i+1         (相当于白嫖到一个点亮的)
                            checkMin(dp[i + 1][y][1][a][b + 1], dp[i][x][y][a][b]);
                        if (a < k && (x || y))//这个点亮之后, 放到其他位置去   (相当于没点亮)
                            checkMin(dp[i + 1][y][0][a + 1][b], dp[i][x][y][a][b] + w[i + 1]);
                    }
                }
            }
        }
    }
    ll ans = INF;
    for (int kk = 0; kk <= k; kk++) {
        for (int x = 0; x <= 1; ++x) {
            for (int y = 0; y <= 1; ++y) {
                if (x || y)
                    checkMin(ans, dp[n][x][y][kk][kk]);
            }
        }
    }
    write(ans), enter;
}
I Game on Plane

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值