2020/5/11 每日一咕

2020/5/11 每日一咕

1.线段树优化dp

Problem - 1216F - Codeforces (Unofficial mirror site by GGAutomaton, accelerated for Chinese users)
You work as a system administrator in a dormitory, which has n n n rooms one after another along a straight hallway. Rooms are numbered from 1 1 1 to n n n.

You have to connect all n n n rooms to the Internet.

You can connect each room to the Internet directly, the cost of such connection for the i i i-th room is i i i coins.

Some rooms also have a spot for a router. The cost of placing a router in the i i i-th room is also i i i coins. You cannot place a router in a room which does not have a spot for it. When you place a router in the room i i i, you connect all rooms with the numbers from m a x ( 1 , i − k ) max(1, i−k) max(1,ik) to m i n ( n , i + k ) min(n, i+k) min(n,i+k) inclusive to the Internet, where k k k is the range of router. The value of k k k is the same for all routers.

Calculate the minimum total cost of connecting all n n n rooms to the Internet. You can assume that the number of rooms which have a spot for a router is not greater than the number of routers you have.

Input

The first line of the input contains two integers n n n and k k k ( 1 ≤ n , k ≤ 2 ⋅ 1 0 5 ) (1≤n,k≤2⋅10^5) (1n,k2105) — the number of rooms and the range of each router.

The second line of the input contains one string s s s of length n n n, consisting only of zeros and ones. If the i i i-th character of the string equals to ‘1’ then there is a spot for a router in the i i i-th room. If the i i i-th character of the string equals to ‘0’ then you cannot place a router in the i i i-th room.

Output

Print one integer — the minimum total cost of connecting all n n n rooms to the Internet.

Examples

input

5 2
00100

output

3

input

6 1
000000

output

21

input

4 1
0011

output

4

input

12 6
000010000100

output

15

Note

In the first example it is enough to place the router in the room 3 3 3, then all rooms will be connected to the Internet. The total cost of connection is 3 3 3.

In the second example you can place routers nowhere, so you need to connect all rooms directly. Thus, the total cost of connection of all rooms is 1 + 2 + 3 + 4 + 5 + 6 = 21 1+2+3+4+5+6=21 1+2+3+4+5+6=21.

In the third example you need to connect the room 1 1 1 directly and place the router in the room 3 3 3. Thus, the total cost of connection of all rooms is 1 + 3 = 4 1+3=4 1+3=4.

In the fourth example you need to place routers in rooms 5 5 5 and 10 10 10. Then all rooms will be connected to the Internet. The total cost of connection is 5 + 10 = 15 5+10=15 5+10=15.

题意

有n个房间,每个房间 i i i都可以花费 i i i使其直连网络。某些特定的房间可以花费 i i i装一个路由,有效半径为k,即 m a x ( 1 , i − k ) max(1, i−k) max(1,ik) ~ m i n ( n , i + k ) min(n, i+k) min(n,i+k)都可以因此连上网络,求让所有房间都连上网络的最小花费。

d p [ i ] [ 01 ] dp[i][01] dp[i][01]为第 i i i个房间放置路由器与否的最小花费。
则不放路由器的房间,要么从前一个不放的+i得到,要么被前面某个路由的包含。
d p [ i ] [ 0 ] = m i n ( d p [ i − 1 ] [ 0 ] , m i n { d p [ 区 间 [ m a x ( 1 , i − k ) , i − 1 ]   ] [ 1 ] } ) dp[i][0]=min(dp[i-1][0],min\{ dp[区间[max(1,i-k),i-1]\ ][1]\}) dp[i][0]=min(dp[i1][0],min{dp[[max(1,ik),i1] ][1]})
放路由的则前面k个放不放都无所谓,所以只要在前面有效半径-1里找一个最小值即可
d p [ i ] [ 1 ] = m i n { d p [ 区 间 [ m a x ( i − k − 1 , 0 ) , i − 1 ]   ] [ 01 ] } + i dp[i][1]=min\{dp[区间[max(i-k-1,0),i-1]\ ][01]\}+i dp[i][1]=min{dp[[max(ik1,0),i1] ][01]}+i
可以看到这里需要一个带修的区间最值查询,而且有两个,上两颗线段树解决。
因为线段树是从1开始建的,所以会查询到0的时候特殊处理一下为0。

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    segment_Tree_min T(n), T1(n);
    T.build(1, n);
    T1.build(1, n);
    vector<vector<ll>> dp(n + 1, vector<ll>(2, inf));
    dp[0][0] = 0;
    for (int i = 1; i <= n; ++i) {
        dp[i][0] = min(dp[i - 1][0] + i, T1.query(max(1, i - k), i - 1));
        if (s[i - 1] == '1') {
            if (i - k - 1 <= 0) {
                dp[i][1] = 0;
            } else {
                dp[i][1] = min(T.query(i - k - 1, i - k - 1),
                               T1.query(i - k - 1, i - k - 1));
            }
            dp[i][1] += i;
            T1.updata(i, i, dp[i][1]);
        }
        T.updata(i, i, dp[i][0]);
    }
    cout << min(dp[n][0], dp[n][1]) << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值