思路:DP,dp[i][j]表示以第i个学生结尾,选取j个人的最大值,注意可能有负数
package l1; import java.util.Scanner; /* * dp[i][j]表示以第i个学生结尾,选取j个人的最大值 * * 还有负数 */ public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] a = new int[n]; for(int i=0; i<n; i++) a[i]=sc.nextInt(); int k = sc.nextInt(), d = sc.nextInt(); long[][] dp = new long[1+n][k+1], dp2 = new long[1+n][1+k]; dp[0][0] = 1; dp2[0][0] = 1; for(int i=1; i<=n; i++) { dp[i][0] = 1; dp2[i][0] = 1; for(int j=1; j<=Math.min(k, i); j++) { for(int p=i-1; i-p<=d && p>=j-1; p--) { if(a[i-1] >= 0) { dp[i][j] = Math.max(dp[i][j], dp[p][j-1]*a[i-1]); dp2[i][j] = Math.min(dp2[i][j], dp2[p][j-1]*a[i-1]); } else { dp[i][j] = Math.max(dp[i][j], dp2[p][j-1]*a[i-1]); dp2[i][j] = Math.min(dp2[i][j], dp[p][j-1]*a[i-1]); } } } } long max = Integer.MIN_VALUE; for(int i=1; i<=n; i++) max = Math.max(max, dp[i][k]); System.out.println(max); } }
public class ME { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Set<Integer> alreadyHave = new HashSet<Integer>(); int cnt = 0; int n = sc.nextInt(); for(int i=0; i<n; i++) { int t = sc.nextInt(); if(!alreadyHave.contains(t)) { Set<Integer> tmp = new HashSet<Integer>(); for(int p : alreadyHave) tmp.add((p ^ t)); alreadyHave.addAll(tmp); alreadyHave.add(t); cnt ++; } } System.out.println(cnt); } } 另外一种解法是:借鉴求矩阵的秩的过程,把线性运算改为异或运算就好了
/* * 通过线性变换求极大线性无关组,这里把“线性变换”改成了“异或变换” * 矩阵化为上下三角,求秩:高斯消元法:https://zh.wikipedia.org/wiki/高斯消去法 * 区别在于线性变化是随便选取一行作为基准让别人消元,这里需要选取最大行,为什么? * 因为无论是线性变换还是异或变换,都是希望先尽量多的消掉高位 * 越大的数意味着高位上为1的越多,这样如果另外一个数高位上为1就可以异或消掉了(如果是0根本就不需要消掉) * 而,如果先选取小的数作为基准,一个更大的数也许就不能消掉高位了 */ public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] a = new int[n]; for(int i=0; i<n; i++) a[i]=sc.nextInt(); for(int i=n; i>0; i--) { Arrays.sort(a, 0, i); for(int j=i-2; j>=0; j--) if((a[i-1] ^ a[j]) < a[j]) a[j] = (a[i-1] ^ a[j]); // 也许没有把a[j]的最高位消除,但是这是最有可能的方案,别的更不可能 } int zero = 0; while(zero<n && a[zero] == 0) zero++; System.out.println(n - zero); } }
package l5; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(), m = sc.nextInt(); int ret = 0; if(n%4==0 || m%4==0) { ret = n*m/2; } else if(n%2==0 && m%2==0) { ret = (n/4*m/4*8) + (n/4*4+m/4*4) + 4; } else { ret = n*m/2 + 1; // 1是剩余的一行多出来的一个,比如奇数行是7,该列可以有4个 } System.out.println(ret); } }
