[入门组模拟赛[难]]游戏
题目描述
乐乐设计了一款游戏。游戏中,玩家需要通过操作改变灯的开关状态获得分
数。
N 盏灯排成一列(编号为 1~N)。一开始,有的灯是开着的,有的灯是关着
的。每盏灯有自己的亮度。现在你可以进行任意次操作(也可以不操作),每次
改变 K 盏连续的灯的开关状态。
最终,你的得分是所有开着的灯的亮度之和。请问得分最大是多少?
输入
第一行,一个正整数T,表示测试数据组数。
对于每组测试数据:
首先是一行两个正整数N,K,意义如题目所述。
接着是 N 个数依次表示 1~N 每盏灯的开关状态。每个数是 0 或 1,分别表
示这盏灯初始时是关的或开的。
最后是 N 个非负整数依次表示 1~N 每盏灯的亮度。
输出
对每组测试数据输出一行。表示最大的得分。
样例输入
3 3 2 0 1 1 3 2 4 10 1 0 0 1 0 1 0 0 1 0 1 1 1 1 3 4 3 4 5 1 5 10 7 1 1 1 1 1 1 1 1 1 1 5 5 3 3 4 3 5 1 1 3
样例输出
7 28 33
提示
共有 10 个测试点。
测试点 1~2:1≤K≤N≤1000,且 N – K≤10;
测试点 3~6:1≤K≤N≤1000, 且 K≤10;
测试点 7~10:1≤K≤N≤1000。
对于所有的测试点, 保证 T≤5, 并且每盏灯亮度都为不超过 1000 的正整数。
代码
#include<bits/stdc++.h> using namespace std; int T,n,k,a[1001],b[1001]; vector<int> p[1001]; int solve() { int sum=0; for(int i=0;i<k;i++) { int num=0,mn=1001; for(int j=0;j<p[i].size();j++) { if(a[p[i][j]]==0) num++; mn=min(mn,b[p[i][j]]); } if(num%2==1) sum+=mn; } return sum; } int main() { scanf("%d",&T); while(T--) { for(int i=0;i<k;i++) p[i].clear(); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int res=0; for(int i=1;i<=n;i++) scanf("%d",&b[i]),res+=b[i]; for(int i=1;i<=n;i++) p[i%k].push_back(i); int ans1=solve(); for(int i=1;i<=k;i++) if(a[i]==1) a[i]=0; else a[i]=1; int ans2=solve(); printf("%d\n",res-min(ans1,ans2)); } return 0; }