2.10
[P2340 USACO03FALL] Cow Exhibition G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)\
- 很不错的一道题,我们考虑把本题转换为01背包,因为每只奶牛只有选或者不选两种可能性
- \(dp[i][j]\)记录为在前i头奶牛中,智商为j时所得到的情商最大数
- 根据01背包,我们只需要枚举i,j即可,也就是奶牛种数和智商的的容量
- 因为存在负数,所以设定中间值400000,可以理解为之前的开端0向右平移了400000个单位
import java.io.*;
import java.util.*;
public class Main implements Runnable {
static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
//static Scanner cin = new Scanner(System.in);
static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));
static final int N = 410;
static final int SUMIQ = (int) 8e5;
static milk[] milks = new milk[N];
static int n;
static int[] dp = new int[SUMIQ + 10];
public static void main(String[] args) {
new Thread(null, new Main(), "", 1 << 29).start();
}
public static int nextInt() throws IOException {
cin.nextToken();
return (int) cin.nval;
}
// public static String next() throws IOException {
// return cin.next();
// }
@Override
public void run() {
try {
n = nextInt();
for (int i = 1; i <= n; i++) {
milks[i] = new milk();
int iq = nextInt();int eq = nextInt();
milks[i].iq = iq; milks[i].eq = eq;
}
Arrays.fill(dp, -0x3f3f3f3f);
dp[400000] = 0;
for (int i = 1; i <= n; i++) {
if (milks[i].iq > 0) {
for (int j = SUMIQ; j >= milks[i].iq; j--) {
dp[j] = Math.max(dp[j], dp[j - milks[i].iq] + milks[i].eq);
}
} else {
for (int j = 1; j <= SUMIQ + milks[i].iq; j++) {
dp[j] = Math.max(dp[j], dp[j - milks[i].iq] + milks[i].eq);
}
}
}
int ans = 0;
for (int i = 400000; i <= SUMIQ; i++) {
if (dp[i] >= 0) {
ans = Math.max(ans, dp[i] + i - 400000);
}
}
cout.println(ans);
cout.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
static class milk {
int iq;
int eq;
}
}
[P1541 NOIP 2010 提高组] 乌龟棋 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- 设数组\(dp[num1][num2][num3][num4]\)为打出卡牌1,卡牌2,卡牌3,卡牌4时所得到的最高分数
- 在设置一个\(score[j]\)数组来存储每个格子的分数即可
import java.io.*;
import java.util.*;
public class Main implements Runnable {
static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
//static Scanner cin = new Scanner(System.in);
static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));
static final int N = 400;
static int[] score = new int[N];
static int[] cardNum = new int[5];
static int n, m;
static int[][][][] dp = new int[45][45][45][45];
public static void main(String[] args) {
new Thread(null, new Main(), "", 1 << 29).start();
}
public static int nextInt() throws IOException {
cin.nextToken();
return (int) cin.nval;
}
// public static String next() throws IOException {
// return cin.next();
// }
@Override
public void run() {
try {
n = nextInt();m = nextInt();
for (int i = 1; i <= n; i++) {
score[i] = nextInt();
}
for (int i = 1; i <= m; i++) {
int x = nextInt();
cardNum[x]++;
}
dp[0][0][0][0] = score[1];
for (int i = 1; i <= 4; i++) {
for (int num1 = 0; num1 <= cardNum[i]; num1++) {
for (int num2 = 0; num2 <= cardNum[i]; num2++) {
for (int num3 = 0; num3 <= cardNum[i]; num3++) {
for (int num4 = 0; num4 <= cardNum[i]; num4++) {
int bushu = num1 + num2 * 2 + num3 * 3 + num4 * 4 + 1;
if (num1 != 0) dp[num1][num2][num3][num4] = Math.max(dp[num1][num2][num3][num4], dp[num1 - 1][num2][num3][num4] + score[bushu]);
if (num2 != 0) dp[num1][num2][num3][num4] = Math.max(dp[num1][num2][num3][num4], dp[num1][num2 - 1][num3][num4] + score[bushu]);
if (num3 != 0) dp[num1][num2][num3][num4] = Math.max(dp[num1][num2][num3][num4], dp[num1][num2][num3 - 1][num4] + score[bushu]);
if (num4 != 0) dp[num1][num2][num3][num4] = Math.max(dp[num1][num2][num3][num4], dp[num1][num2][num3][num4 - 1] + score[bushu]);
}
}
}
}
}
cout.println(dp[cardNum[1]][cardNum[2]][cardNum[3]][cardNum[4]]);
cout.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
P4310 绝世好题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- 暴力的解法是设置\(dp[i]\)前i个数中最长子序列,转换成了最长上升子序列问题。得了90分,寻找正确解
- 考虑到只要我们两个数的同一位同为1,那么就符合\(a[i]\&a[j]=1\)条件,那么我们可以在枚举每一个数时,去枚举这个数的每一位,可以用这个写法
((1 << j) & x),记得最后更新一下即可
import java.io.*;
import java.util.*;
public class Main implements Runnable {
static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
//static Scanner cin = new Scanner(System.in);
static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));
static int n;
static final int N = (int) (1e5 + 10);
static long[] a = new long[N];
static int[] dp = new int[32];
public static void main(String[] args) {
new Thread(null, new Main(), "", 1 << 29).start();
}
public static int nextInt() throws IOException {
cin.nextToken();
return (int) cin.nval;
}
// public static String next() throws IOException {
// return cin.next();
// }
@Override
public void run() {
try {
n = nextInt();
for (int i = 1; i <= n; i++) {
int x = nextInt();
int max = 0;
for (int j = 0; j <= 31; j++) {
if(((1 << j) & x) != 0) {
max = Math.max(max, dp[j] + 1);
}
}
for (int j = 0; j <= 31; j++) {
if(((1 << j) & x) != 0) {
dp[j] = Math.max(dp[j], max);
}
}
}
int ans = 0;
for (int i = 0; i <= 31; i++) {
ans = Math.max(ans, dp[i]);
}
cout.println(ans);
cout.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
浙公网安备 33010602011771号