1、瞌睡:
已知小易對一堂課每分鐘知識點的感興趣程度,並以分數量化,以及他在這堂課上每分鐘是否會睡着,你可以叫醒他一次,這會讓他在接下來的k分鐘內保持清醒。求一種方案最大化他聽到知識點的最大興趣值。
第一行:輸入n,k(1<=n,k<10^5),表示這堂課持續的時間,以及叫醒小易能讓他保持清醒的時間。
第二行:n個數,a1,a2,a3..an(1--10^4)表示對每分鐘知識點的興趣評分
第三行:n個數,t1,t2....tn表示每分鐘小易是否清醒,1表示清醒,0表示睡着。
輸出:聽到知識點的最大興趣值。
6 3
1 3 5 2 5 4
1 1 0 1 0 0
16
代碼如下:
首先,清醒的時候的興趣值是必須要加上的;有個最優值就是:睡着之後被叫醒。
看他說這是貪心,還得看看。==》90%
import java.util.Scanner;
public class LastT1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int i=0;
int[] scores = new int[n];
while(i<n){
scores[i] = sc.nextInt();
i++;
}
int[] wake = new int[n];
i = 0;
while (i<n){
wake[i] = sc.nextInt();
i++;
}
int maxValue = 0;//睡着後被叫醒的最大收益
int sum = 0;//沒睡覺時候的收益,這是必須的
for(int j=0;j<n;j++){
if(wake[j] == 0){
int tmp = 0;//睡着了,但叫醒後的收益
for(int t=j;t<j+k;t++){//叫醒後的k分鐘清醒
if(t >= n)break;//超過數組長度,結束就好
if(wake[t] == 0)//如果爲0,表示之前瞌睡,加上該值
tmp += scores[t];
}
if(maxValue < tmp)
maxValue = tmp;
}else {//此時沒睡着
sum += scores[j];
}
}
System.out.println(maxValue + sum);
}
}
參考:https://www.nowcoder.com/discuss/93132
第二種方法,使用滑動窗口
import java.util.Scanner;
public class LastT1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int i=0;
int[] scores = new int[n];
while(i<n){
scores[i] = sc.nextInt();
i++;
}
int[] wake = new int[n];
i = 0;
while (i<n){
wake[i] = sc.nextInt();
i++;
}
int sum = 0;
i=0;
for(;i<n;i++){//爲1的肯定要加上
if(wake[i] == 1)
sum += scores[i];
}
i = 0;
for(;i<k;i++){//設大小爲k的滑動窗口**保證大小爲k的窗口
if(wake[i] == 0){
sum += scores[i];
}
}
int max = sum;
for(i=k;i<n;i++){//k之後。。。
if(wake[i-k] == 0)//如果第一個爲0,減去第一個
sum -= scores[i-k];
if(wake[i] == 0){//當前這個爲0,加上這一個
sum += scores[i];
if(max < sum)
max = sum;
}
}
System.out.println(max);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int i=0;
int[] scores = new int[n];
while(i<n){
scores[i] = sc.nextInt();
i++;
}
int[] wake = new int[n];
i = 0;
while (i<n){
wake[i] = sc.nextInt();
i++;
}
int sum = 0;
i=0;
for(;i<n;i++){
if(wake[i] == 1)
sum += scores[i];
}
int slow = 0;
int fast = k-1;
int max = 0;
i= 0;
for(;i<=fast;i++){//當slow爲0的時候
if(wake[i] == 0){
sum += scores[i];
}
}
max = sum;
fast++;
while(fast < scores.length){
if(wake[slow] ==0)
sum -= scores[slow];
if(wake[fast] == 0){
sum += scores[fast];
if(max < sum)
max = sum;
}
slow++;
fast++;
}
System.out.println(max);
}
我更喜歡這樣兩個指針的滑動窗口!注意前k個數組還是得手動的往裏加!然後從fast++開始遍歷。
我也不知道爲啥,我的第一反應是遞歸,沒做出來。這種情況下,想不出來關於k分鐘清醒參數如何進行使用的途徑,==》反正用遞歸不合適!
2、蘋果堆,將前面的數相加,然後進行搜索即可!但是這樣會超時===》此時已經是有序數組了,所以使用二分查找即可!
示例
輸入
5
2 7 3 4 9
3
1 25 11
輸出
1
5
3
import java.util.Scanner;
public class T2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.nextLine().trim());
int []IndexOfApple = new int[n];
String[] rawDatas = scanner.nextLine().trim().split(" ");
IndexOfApple[0] = Integer.parseInt(rawDatas[0]);
for (int i = 1; i < n ; i++) {
int tmp = Integer.parseInt(rawDatas[i]);
IndexOfApple[i] = IndexOfApple[i-1] + tmp;
}
int m = Integer.parseInt(scanner.nextLine().trim());
int []number = new int[m];
int []res = new int[m];
rawDatas = scanner.nextLine().trim().split(" ");
for (int i = 0; i < m ; i++) {
number[i] = Integer.parseInt(rawDatas[i]);
}
for (int i = 0; i < m; i++) {
//System.out.println(function(IndexOfApple,number[i]));
//System.out.println(binarySearch(IndexOfApple,number[i]) + 1);
System.out.println(function1(IndexOfApple,number[i]) + 1);
}
}
private static int function1(int[]IndexOfApple, int value){
int low = 0;
int high = IndexOfApple.length - 1;
while(low <= high){
int mid = (low + high) / 2;
if(IndexOfApple[mid] > value){
high = mid - 1;
}else if(IndexOfApple[mid] < value){
low = mid + 1;
}else{
return mid;
}
}
return low;
}
public static int binarySearch(int[] a,int fromIndex,int toIndex,int value){
int low=fromIndex;
int high=toIndex-1;
while(low<high){
int mid=(low+high)>>>1;
int midVal=a[mid];
if(midVal<value)
low=mid+1;
else
high=mid;
}
return low;
}
private static int function(int[]IndexOfApple, int index){
if (index <= 0)
return -1;
int res = 0;
for (int i=0;i<IndexOfApple.length;i++) {
if(index <= IndexOfApple[i]){
res = i;
break;
}
}
return res+1;
}
}
3、每個單詞都包含n個‘a’,m個‘z’,並且所有單詞按字典序排列。請找出第k個單詞。若無解,返回-1===》n個a和m個z組成的字典序字符串集,查找第k個字是什麼?
輸入描述
第一行爲三個數,分別爲a的個數n,z的個數m,第k個字符串。
輸出描述
第k個字符串
示例
輸入
1
2 2 6
輸出
1
zzaa
直接想法就是,使用全排列,然後排序即可=》這樣只能通過20%。
全排列的算法如下(模板):
static ArrayList<String> list = new ArrayList<>();
public static void permutation(char[] arr,int start,int end){
if(start == end){
String str = new String(arr);
if(list.indexOf(str) == -1)
list.add(str);
}else{
for(int i=0;i<arr.length;i++){
swap(arr,start,i);
permutation(arr,start+1,end);
swap(arr,start,i);
}
}
}
重點信息:只有a,z!
動態規劃:dp[i][j]表示i個a和j個z的方案數=》這個我不會
參考:https://www.nowcoder.com/discuss/93285
https://fengxc.me/2018%E7%BD%91%E6%98%93%E7%AC%94%E8%AF%95%E9%A2%98%E5%8F%8A%E8%A7%A3%E7%AD%94-Java.html#more
https://www.nowcoder.com/questionTerminal/12b1b8ef17e1441f86f322b250bff4c0 這個講解最好
https://blog.csdn.net/jiang199235jiangjj/article/details/7432601排列組合 爲什麼呢?