[入门组模拟赛[难]]游戏

题目描述

乐乐设计了一款游戏。游戏中,玩家需要通过操作改变灯的开关状态获得分
数。
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;
}
posted @ 2020-07-18 14:35  牛大了的牛大  阅读(183)  评论(0编辑  收藏  举报