dp[di][0]表示前i个数字合法,且第i个数字为0的最小操作数
dp[i][1]表示前i个数字合法,且第i个数字为1的最小操作数
dp[i][0]有两种情况,1)取i-1为0时的合法状态转移,2)取i-1为1的合法状态转移,s[i]为1需要多操作一次,把s[i]变为0dp[i][1]有两种情况,1)将前i-1个数字全变为0,2)取i-m的合法状态,并将i-m到i之间的1变为0,s[i]为0需要多操作一次将其变为1
int dp[N][2];
int a[N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
IO;
int t; cin >> t;
while (t--)
{
int n, m; cin >> n >> m;
string s; cin >> s; s = ' ' + s;
for (int i = 1; i <= n; i++)
a[i] = a[i - 1] + s[i] - '0';//求得前缀和,方便计算区间内 1 的个数
for (int i = 1; i <= n; i++)
{
int p = max(0, i - m);
dp[i][0] = min(dp[i - 1][0], dp[i - 1][1] )+ (s[i] == '1');
dp[i][1] = min(a[i - 1], dp[p][1] + a[i - 1] - a[p]) + (s[i] == '0');
}
cout << min(dp[n][0], dp[n][1]) << endl;
}
return 0;
}