题目描述:
C市现在要转移一批罪犯到D市,C市有n名罪犯,按照入狱时间有顺序,另外每个罪犯有一个罪行值,值越大罪越重。现在为了方便管理,市长决定转移入狱时间连续的c名犯人,同时要求转移犯人的罪行值之和不超过t,问有多少种选择的方式?
输入描述:
第一行数据三个整数:n,t,c(1≤n≤2e5,0≤t≤1e9,1≤c≤n),第二行按入狱时间给出每个犯人的罪行值ai(0≤ai≤1e9)
输入例子:
3 100 2
1 2 3
输出例子:
2
我的第一次代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
//关押的罪犯数量
int criminalNumber = sc.nextInt();
//最大罪行值
int maxCrime = sc.nextInt();
//转移的罪犯数量
int transferNumber = sc.nextInt();
//每个罪犯的罪行值
int[] crime = new int[criminalNumber];
for(int i = 0;i<criminalNumber;i++){
crime[i] = sc.nextInt();
}
//符合条件数量
int count = 0;
//两次for循环,其实计算量很大
for(int i = 0;i<=criminalNumber-transferNumber;i++){
int sum = 0;
for(int j = 0;j<transferNumber;j++){
sum+=crime[i+j];
}
//如果罪行值的和小于最大罪行值,则满足条件
if(sum<=maxCrime){
count++;
}
}
System.out.println(count);
}
}
}
但是这样的话,没有用到动态规划的思想,没有复用。于是我去网上查了一下,有一种叫做滑动窗口的方法,牛!
第二次代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
//关押的罪犯数量
int criminalNumber = sc.nextInt();
//最大罪行值
int maxCrime = sc.nextInt();
//转移的罪犯数量
int transferNumber = sc.nextInt();
//每个罪犯的罪行值
int[] crime = new int[criminalNumber];
for(int i = 0;i<criminalNumber;i++){
crime[i] = sc.nextInt();
}
//符合条件数量
int count = 0;
//转移罪犯的罪行值的和
int sum = 0;
for(int i = 0;i<transferNumber;i++){
sum+=crime[i];
}
if(sum<maxCrime)
count++;
//这里很关键,用了复用的思想,后边加上一个,前边减去一个,中间的都被复用了
for(int i = transferNumber;i<criminalNumber;i++){
sum = sum + crime[i] - crime[i-transferNumber];
if(sum<maxCrime)
count++;
}
System.out.println(count);
}
}
}