第一行 n (1 <= n <= 105), k (0 <= k <= 105) ,表示这堂课持续多少分钟,以及叫醒小易一次使他能够保持清醒的时间。
第二行 n 个数,a1, a2, ... , an(1 <= ai <= 104) 表示小易对每分钟知识点的感兴趣评分。
第三行 n 个数,t1, t2, ... , tn 表示每分钟小易是否清醒, 1表示清醒。
小易这堂课听到的知识点的最大兴趣值。
6 3 1 3 5 2 5 4 1 1 0 1 0 0
16
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int k = in.nextInt(); int[] score = new int[n]; int[] status = new int[n]; for (int i = 0; i < n; i++) { score[i] = in.nextInt(); //读入兴趣点 } int basic = 0; //必得分 for (int i = 0; i < n; i++) { status[i] = in.nextInt(); //读入状态 basic += score[i] * status[i]; //累加必得分 } int extra = 0; //叫醒后k分钟内的最大额外分 for (int i = 0; i < n - k + 1; i++) { int temp = 0; //第i分钟到i+k分钟的额外分 for (int j = 0; j < k; j++) { //计算这一段的额外分 temp += score[i + j] * (1 - status[i + j]);//核心,只累加额外得分 } extra = extra > temp ? extra : temp;//比较最大额外分 } System.out.print(basic + extra); //最终得分为基础+额外 } //为什么循环到n-k+1就结束了,因为后面时间内的得分不会超过最后一次计算的额外分 }极简思路
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int k=sc.nextInt(); int[] interest=new int[n]; int[] awake=new int[n]; long sum1=0; for(int i=0;i<n;i++){ interest[i]=sc.nextInt(); } for(int i=0;i<n;i++){ awake[i]=sc.nextInt(); if(awake[i]==1) sum1+=interest[i]; } int max=0; for(int i=0;i<=n-k;i++){ int sum=0; for(int j=0;j<k;j++){ if(awake[i+j]==0) sum+=interest[i+j]; } if(sum>max) max=sum; } System.out.println(max+sum1); } }遍历所有清醒时刻的兴趣总和,然后循环遍历k个节点的兴趣和,期间如过i+j节点值为1,表示在第一次计算总和时已经考虑,不予以添加
package test.alogorithm.test; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int number = sc.nextInt(); int time = sc.nextInt(); int count=0,max=0,temp=0; //兴趣评分列表 int[] a=new int[number]; for (int i=0;i<number;i++){ a[i]=sc.nextInt(); } //清醒列表 int[] b=new int[number]; for (int i=0;i<number;i++){ b[i]=sc.nextInt(); } //判断如果叫醒时间大于课堂时间直接计算出所有和 if (time>=number){ for (int i=0;i<number;i++){ count+=a[i]; } System.out.println(count); }else { //------> 寻找最大值 for (int i=0;i<number-time;i++){ if (b[i]==0){ for (int j=i;j<i+time;j++){ if (b[j]==0) { temp += a[j]; } } if (temp>max) max=temp; //注意临时变量的初始化 temp=0; } } //直接计算状态为0的值之和的最大值 for (int i=number-time;i<number;i++){ if (b[i]==0) { temp += a[i]; } if (max<temp) max=temp; } //<------ 寻找最大值 //计算出状态为1的值之和 for (int i=0;i<number;i++){ if (b[i]==1){ count+=a[i]; } } //输出加上状态为0的值之和的最大值 System.out.println(count+max); } } }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner in = new Scanner(System.in); int n = in.nextInt(), k = in.nextInt(); int[][] list = new int[n][2]; for (int i = 0; i < 2; i++) { for (int j = 0; j < n; j++) { list[j][i] = in.nextInt(); } } int max = 0; for (int i = 0, count = 0; i < n; i++) { if(list[i][1] == 0) count += list[i][0]; if(i-k >= 0 && list[i-k][1] == 0) count -= list[i-k][0]; max = Math.max(max,count); } for (int i = 0; i < n; i++) { if(list[i][1] == 1) max += list[i][0]; } System.out.println(max); } }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int k=sc.nextInt(); int[] a=new int[n]; int[] t=new int[n]; int[] sum=new int[2*n]; for(int i=0;i<n;i++){ a[i]=sc.nextInt(); } for(int i=0;i<n;i++){ t[i]=sc.nextInt(); } for(int i=0;i+k<=n;i++){ int b[]=new int[n]; for(int j=i;j<i+k;j++){ if(t[j]==0){ b[j]=1;//记录原先修改前的a[j]的位置; t[j]=1; } } for(int j=0;j<n;j++){ sum[i]+=a[j]*t[j]; if(b[j]==1){ t[j]=0;//改回原来的数据; } } } Arrays.sort(sum); System.out.print(sum[sum.length-1]); } }
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner input = new Scanner(System.in); int n = input.nextInt(); int k = input.nextInt(); int a[] = new int[n]; int t[] = new int[n]; for(int i = 0; i < n; i++) { a[i] = input.nextInt(); } for(int i = 0; i < n; i++) { t[i] = input.nextInt(); } input.close(); System.out.println(Solution(n, k, a, t)); } public static int Solution(int n, int k, int[] a, int[] t) { if(k >= n) return Sum(a); int sum1 = 0; int num0 = n; for(int i = 0; i < n; i++) if(t[i] == 1) { sum1 += a[i]; num0 --; } if(num0 < 2) return Sum(a); int sum0[] = new int[num0]; int index = 0; for(int i = 0; i < a.length; i++) { if(t[i] == 0) { for(int j = i; j < i + k && j < n; j++) { if(t[j] == 0) sum0[index] += a[j]; } index ++; } } int Msum0 = sum0[0]; for(int i = 0; i < num0; i++) if(sum0[i] > Msum0) Msum0 = sum0[i]; return sum1 + Msum0; } public static int Sum(int[] a) { int sum = 0; for(int i = 0; i< a.length; i++) { sum += a[i]; } return sum; } }
主要思想是将知识点分值化为两部分来分别计算,一部分为保持清醒的时段,此时段的知识点分值固定不受叫醒时间影响;另一部分为根据叫醒时间额外增加的分值,遍历所有可能被叫醒的点,并计算出从该点开始后k个点内新增的知识点分,比较各个可叫醒点的该值取最大。需注意的是在求取可叫醒点i的新增知识点分时,若直接再使用循环遍历后面k个点复杂度较高,此处使用一个睡眠点分值的累加数组来进行优化。
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner scan = new Scanner(System.in); int n = scan.nextInt(); int k = scan.nextInt(); int[] val = new int[n]; int[] state = new int[n]; //保存瞌睡时的累计评分 int sleep = 0; int[] sleepval = new int[n]; for(int i=0;i<n;i++){ val[i] = scan.nextInt(); } for(int i=0;i<n;i++){ state[i] = scan.nextInt(); if(state[i]==0){ sleep += val[i]; } sleepval[i] = sleep; } Main ma = new Main(); int res = ma.getMaxVal(val,state,n,k,sleepval); System.out.println(res); } public int getMaxVal(int[] val,int[] state,int n,int k,int[] sleepval){ int res = 0; int addval = 0; for(int i=0;i<n;i++){ if(state[i]==1) res += val[i]; else{ int wakeval = 0; if(i+k-1>=n){ wakeval =(i>0)?(sleepval[n-1]-sleepval[i-1]):sleepval[n-1]; }else{ wakeval = (i>0)?(sleepval[i+k-1]-sleepval[i-1]):sleepval[i+k-1]; } addval = addval>=wakeval?addval:wakeval; } } return res+addval; } }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); int[] interset = new int[n]; int[] isAwake = new int[n]; int[] sumInterestOf0 = new int[n]; for (int i = 0; i < n; i++) { interset[i] = sc.nextInt(); } int sum0 = 0; int sum1 = 0; for (int i = 0; i < n; i++) { isAwake[i] = sc.nextInt(); if (isAwake[i] == 1) { sum1 += interset[i]; } else { sum0 += interset[i]; } sumInterestOf0[i] = sum0; } int cur = 0; int max = Integer.MIN_VALUE; for (int i = 0; i < n; i++) { if (isAwake[i] == 0) { if (i + k - 1 > n - 1) { cur = sumInterestOf0[n - 1] - (i - 1 >= 0 ? sumInterestOf0[i - 1] : 0); } else { cur = sumInterestOf0[i + k - 1] - (i - 1 >= 0 ? sumInterestOf0[i - 1] : 0); } max = cur > max ? cur : max; } } System.out.println(sum1 + max); } }