Question
有n盏灯,0代表暗,1代表亮,相邻两个1之间为周期k,求出最少的改变次数
Solution
First
贪心方法
详见博客https://blog.csdn.net/cheng__yu_/article/details/106145027
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define maxn 1005
#define inf 0x3f3f3f
#define endl '\n'
#pragma GCC optimize(2)
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long ll;
//ll fpm(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
//ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
//ll fastPow(ll a,ll b) {ll res=1; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a;a=a*a;}return res;}
int t;
int n,k;
string s;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
cin>>n>>k;
cin>>s;
int cnt=count(s.begin(),s.end(),'1');
int anss=inf;
for(int i=0;i<k;i++){
int temp=0;
for(int j=i;j<n;j+=k){
if(s[j]=='0') temp++;
else temp--;
temp=min(temp,0);
anss=min(anss,cnt+temp);
}
}
cout<<anss<<endl;
}
return 0;
}
Second
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define maxn 1005
#define inf 0x3f3f3f
#define endl '\n'
#pragma GCC optimize(2)
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long ll;
//ll fpm(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
//ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
//ll fastPow(ll a,ll b) {ll res=1; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a;a=a*a;}return res;}
int t;
int n,k;
string s;
int dp[1000050][2];
int pre[1000050];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
cin>>n>>k;
cin>>s;
s="0"+s;
for(int i=1;i<=n;i++){
pre[i]=pre[i-1]+(s[i]=='1');
}
for(int i=1;i<=n;i++){
int z=max(0,i-k);
dp[i][0]=min(dp[i-1][1],dp[i-1][0])+(s[i]=='1');
dp[i][1]=min(dp[z][1]+pre[i-1]-pre[z],pre[i-1])+(s[i]=='0');
}
int ans=min(dp[n][0],dp[n][1]);
cout<<ans<<endl;
}
return 0;
}