https://hihocoder.com/contest/offers75/problems
题目1 : 工作城市分配
题目2 : 工作城市分配2
思路:DP
package l751;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int[][]a=new int[2*n][2];
for(int i=0;i<2*n;i++) {
a[i][0]=sc.nextInt();
a[i][1]=sc.nextInt();
}
int[][]dp=new int[2*n][1+n];
dp[0][0]=a[0][1];
dp[0][1]=a[0][0];
for(int i=1;i<2*n;i++) {
for(int j=0;j<=n;j++){
if(j==0) dp[i][j]=dp[i-1][j]+a[i][1];
else dp[i][j]=Math.max(dp[i-1][j]+a[i][1], dp[i-1][j-1]+a[i][0]);
}
}
System.out.println(dp[2*n-1][n]);
}
}
package l752;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int[][]a=new int[3*n][3];
for(int i=0;i<3*n;i++) {
a[i][0]=sc.nextInt();
a[i][1]=sc.nextInt();
a[i][2]=sc.nextInt();
}
int[][][]dp=new int[3*n][1+n][1+n];
dp[0][0][0]=a[0][2];
dp[0][0][1]=a[0][1];
dp[0][1][0]=a[0][0];
for(int i=1;i<3*n;i++) {
for(int j=0;j<=n;j++){
for(int k=0;k<=n;k++) {
dp[i][j][k]=dp[i-1][j][k]+a[i][2];
if(j!=0) dp[i][j][k]=Math.max(dp[i][j][k], dp[i-1][j-1][k]+a[i][0]);
if(k!=0) dp[i][j][k]=Math.max(dp[i][j][k], dp[i-1][j][k-1]+a[i][1]);
}
}
}
System.out.println(dp[3*n-1][n][n]);
}
}
题目4 : 栈的加强版
比赛一直想用线段树+interval stabbing,WA
看别人提交有更简单的方法:打个标记就好了,每次弹出的时候输出本来的值和在那个位置上的标记,然后标记下传。
如果inc不是从栈底开始的,还是可以用栈,只需要在相应位置打上减的标记
package l753;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int[] a = new int[200001], add = new int[200001];
int p=1;
for(int i=0;i
线段树WA版
package l753;
import java.util.Scanner;
import java.util.Stack;
public class CopyOfMain {
public static int[] bits = new int[100001], a = new int[100001];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
Stackst=new Stack();
for(int i=0;i0) {
res+=bits[i];
i-=lowbit(i);
}
return res;
}
private static void add(int i, int v) {
while(i