2019.5.16
有一堆牛要过河,河的长度是l,河中间有n个石头,牛只能踩着石头过河,问去掉m个石头后(去掉这m个石头的方式是随机的)的每种情况牛能走的石头间距最小值中,最大的那一个是多少。
输入:25 5 2//河的长度,一共有几块石头,去掉m块
2 14 11 21 17//这n块石头的位置
输出:4
思路:二分距离 check函数注意写法
1 importjava.util.Arrays;2 importjava.util.Scanner;3
4 public classMain {5 static intn,m;6 static intlen;7 static int [] b = new int [50010];8 static boolean check(intx) {9 int cnt = 0;10 int pos = 0;11
12 for(int i=1;i<=n+1;i++) {13
14 if(b[i]-b[pos]
16 cnt++;17 if(cnt>m)18 return false;19 }20 else
21 pos =i;22 }23 return true;24 }25 public static voidmain(String[] args) {26 Scanner cin = newScanner(System.in);27 len =cin.nextInt();28 n =cin.nextInt();29 m =cin.nextInt();30 for(int i=1;i<=n;i++)31 b[i] =cin.nextInt();32 b[0] = 0;33 b[n+1] =len;34 Arrays.sort(b, 0, n+2);35
36 int l = 0, r =len;37 int ans = 0;38 while(l<=r) {39 int mid = (l+r)/2;40 if(check(mid)) {41 l = mid + 1;42 ans =mid;43 }44 else
45 r = mid - 1;46 }47 System.out.println(ans);48 }49 }
2019.5.17
昨天肚子疼,没怎么干活 今天补上。
dijkstra 用我自己写的怎么写怎么RE,改成了某大神的:
5个顶点1~5,5条双向边。求从1到n的最短路
5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100
输出 90
1 import java.util.Arrays;2 import java.util.PriorityQueue;3 import java.util.Scanner;4
5 class node implements Comparable{6 intto;7 intw;8 intnext;9 public node(int to,int w,intnext) {10 this.to=to;11 this.w =w;12 this.next =next;13 //TODO Auto-generated constructor stub
14 }15 @Override16 public intcompareTo(node x) {17 //TODO Auto-generated method stub
18 return this.w-x.w;19 }20 }21 public classMain {22 static final int inf = 0x3f3f3f3f;23 static intm,n,cnt;24 staticnode [] e;25 static int[] vis,dis,head;26 static PriorityQueue q = new PriorityQueue();27 static voidinit() {28 e = new node[2*m];29 head = new int [n+10];30 vis = new int [n+10];31 dis = new int [n+10];32 Arrays.fill(dis, inf);33 Arrays.fill(head, -1);34 cnt = 0;35 }36 static void add(int x,int y,intw) {37 e[cnt] = newnode(y, w, head[x]);38 head[x] = cnt++;39 }40 static void dijkstra(intst) {41 dis[st] = 0;42 q.offer(new node(st, 0, 0));43 while(!q.isEmpty()) {44 int pos =q.poll().to;45 if(vis[pos]==1)46 continue;47 vis[pos] = 1;48 for(int i=head[pos];i!=-1;i=e[i].next) {49 int to =e[i].to;50 if(dis[to]>dis[pos]+e[i].w) {51 dis[to] = dis[pos] +e[i].w;52 q.offer(new node(to, dis[to], 0));53 }54 }55 }56 System.out.println(dis[n]);57 }58 public static voidmain(String[] args) {59 Scanner cin = new Scanner(System.in);60 m =cin.nextInt();61 n =cin.nextInt();62 init();63 inta,b,c;64 for(int i=0;i
5.19
tarjan强连通:
题目描述
在幻想乡,上白泽慧音是以知识渊博闻名的老师。春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄。因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点。人间之里由N个村庄(编号为1..N)和M条道路组成,道路分为两种一种为单向通行的,一种为双向通行的,分别用1和2来标记。如果存在由村庄A到达村庄B的通路,那么我们认为可以从村庄A到达村庄B,记为(A,B)。当(A,B)和(B,A)同时满足时,我们认为A,B是绝对连通的,记为。绝对连通区域是指一个村庄的集合,在这个集合中任意两个村庄X,Y都满足。现在你的任务是,找出最大的绝对连通区域,并将这个绝对连通区域的村庄按编号依次输出。若存在两个最大的,输出字典序最小的,比如当存在1,3,4和2,5,6这两个最大连通区域时,输出的是1,3,4。
输入输出格式
输入格式:
第1行:两个正整数N,M
第2..M+1行:每行三个正整数a,b,t, t = 1表示存在从村庄a到b的单向道路,t = 2表示村庄a,b之间存在双向通行的道路。保证每条道路只出现一次。
输出格式:
第1行: 1个整数,表示最大的绝对连通区域包含的村庄个数。
第2行:若干个整数,依次输出最大的绝对连通区域所包含的村庄编号。
输入输出样例
输入样例#1:
复制
5 5
1 2 1
1 3 2
2 4 2
5 1 2
3 5 1
输出样例#1: 复制
3
1 3 5
说明
对于60%的数据:N <= 200且M <= 10,000
对于100%的数据:N <= 5,000且M <= 50,000
1 import java.util.ArrayList;2 import java.util.Scanner;3
4 public classMain {5 static intn,m;6 static int[] dfn,sta,vis,low;7 static int top=-1,sum,cnt;8 static ArrayList v[] = new ArrayList[50010] ;9 static void tarjan(intu) {10 dfn[u] = low[u] = cnt++;11 sta[++top] =u;12 vis[u] = 1;13 for(int i=0;i
25 }26 if(dfn[u]==low[u]) {27 int num = 0;28 while(sta[top]!=u) {29 num++;30 vis[sta[top--]] = 0;31 }32 vis[sta[top--]] = 0;33 num++;34 if(num>1)35 sum++;36 }37 }38 public static voidmain(String[] args) {39 Scanner cin = new Scanner(System.in);40 n =cin.nextInt();41 m =cin.nextInt();42 dfn = new int [n+10];43 sta = new int [n+10];44 vis = new int [n+10];45 low = new int [n+10];46
47 for(int i=0;i<50010;i++) {48 v[i] = new ArrayList();49 }50 for(int i=0;i
有color版:
1 import java.util.ArrayList;2 import java.util.Scanner;3
4 public classMain {5 static intn,m;6 static int top = -1,cnt,sum,ans,ansc;7 static int[] dfn,vis,sta,low,color;8 static ArrayList v[] = new ArrayList[5010];9 static void tarjan(intu) {10 dfn[u] = low[u] = cnt++;11 vis[u] = 1;12 sta[++top] =u;13 for(int i=0;ians) {36 ans =num;37 ansc =sum;38 }39 }40 }41 public static voidmain(String[] args) {42 Scanner cin = new Scanner(System.in);43 n =cin.nextInt();44 m =cin.nextInt();45 for(int i=0;i();47 dfn = new int [n+10];48 vis = new int [n+10];49 sta = new int [n+10];50 low = new int [n+10];51 color = new int [n+10];52 for(int i=1;i<=m;i++) {53 intx,y,op;54 x =cin.nextInt();55 y =cin.nextInt();56 op =cin.nextInt();57 if(op==1) {58 v[x].add(y);59 }else{60 v[x].add(y);61 v[y].add(x);62 }63 }64 for(int i=1;i<=n;i++) {65 if(dfn[i]==0) {66 tarjan(i);67 }68 }69 System.out.println(ans);70 for(int i=1;i<=n;i++) {71 if(color[i]==ansc) {72 System.out.print(i+" ");73 }74 }75 }76 }
dfs
速算24点
1 import java.util.Arrays;2 import java.util.Scanner;3
4 public classMain {5 static int [] num = new int [5];6 static int [] a = new int [5];7 static int [] vis = new int [5];8 static intflag;9 static void check(int sum,int cur,intstep) {10 if(flag==1)11 return;12 if(step==3) {13 if(sum+cur==24||sum-cur==24||sum*cur==24)14 flag = 1;15 if(cur!=0&&sum%cur==0)16 if(sum/cur==24)17 flag = 1;18 return;19 }20 check(sum+cur, num[step+1], step+1);21 check(sum-cur, num[step+1], step+1);22 check(sum*cur, num[step+1], step+1);23 if(cur!=0&&sum%cur==0)24 check(sum/cur, num[step+1], step+1);25 check(sum, cur+num[step+1], step+1);26 check(sum, cur-num[step+1], step+1);27 check(sum, cur*num[step+1], step+1);28 if(num[step+1]!=0&&cur%num[step+1]==0)29 check(sum, cur/num[step+1], step+1);30 }31 static void dfs(intstep) {32 if(step==4) {33 check(num[0],num[1],1);34 return;35 }36 for(int i=0;i<4;i++) {37 if(vis[i]==0) {38 vis[i] = 1;39 num[step] =a[i];40 dfs(step+1);41 vis[i] = 0;42 }43 }44 }45 public static voidmain(String[] args) {46 Scanner cin = new Scanner(System.in);47 while(cin.hasNext()) {48 flag = 0;49 String ss =cin.nextLine();50 String [] s = ss.split(" ");51 for(int i=0;i<4;i++) {52 if(s[i].compareTo("0")>=0&&s[i].compareTo("9")<=0)53 a[i] =Integer.parseInt(s[i]);54 else if(s[i].equals("A"))55 a[i] = 1;56 else if(s[i].equals("10"))57 a[i] = 10;58 else if(s[i].equals("J"))59 a[i] = 11;60 else if(s[i].equals("Q"))61 a[i] = 12;62 else if(s[i].equals("K"))63 a[i] = 13;64 }65 Arrays.sort(a, 0,4);66 for(int i=0;i<5;i++)67 vis[i] = 0;68 dfs(0);69 if(flag==1)70 System.out.println("Yes");71 else
72 System.out.println("No");73 }74 }75 }
单调栈:
题意:给你一个非负整数数组,定义某个区间的参考值为:区间所有元素的和乘以区间最小元素。求该数组中的最大参考值以及对应的区间。
比如说有6个数3 1 6 4 5 2
最大参考值为6,4,5组成的区间,区间最小值为4,参考值为4*(6+5+4)=60
数据范围1<=n<=100000;
1 import java.util.Scanner;2 import java.util.Stack;3
4 public classMain{5 static intn;6 static int[] l,r;7 static long[] a,sum;8 public static voidmain(String[] args) {9 Scanner cin = new Scanner(System.in);10 n =cin.nextInt();11 a = new long [n+10];12 l = new int [n+10];13 r = new int [n+10];14 sum = new long [n+10];15 for(int i=1;i<=n;i++) {16 a[i] =cin.nextLong();17 sum[i] = sum[i-1]+a[i];18 }19 Stacks = new Stack();20 for(int i=1;i<=n;i++) {21 while(!s.isEmpty()&&a[s.peek()]>=a[i])22 s.pop();23 if(s.isEmpty())24 l[i] = 0;25 else
26 l[i] =s.peek();27 s.push(i);28 }29 while(!s.isEmpty())30 s.pop();31 for(int i=n;i>=1;i--) {32 while(!s.isEmpty()&&a[s.peek()]>=a[i])33 s.pop();34 if(s.isEmpty())35 r[i] = n+1;36 else
37 r[i] =s.peek();38 s.push(i);39 }40 int posl = 0,posr = 0;41 long ans = -1;42 for(int i=1;i<=n;i++) {43 //System.out.println("i="+i+" "+l[i]+" "+r[i]);
44 long tmp = a[i]*(sum[r[i]-1]-sum[l[i]]);45 //System.out.println(tmp);
46 if(tmp>ans) {47 ans =tmp;48 posl = l[i] + 1;49 posr = r[i] - 1;50 }51 }52 System.out.println(ans);53 System.out.println(posl+" "+posr);54 }55 }
5.20 今天是520鸭!!
简单尺取:
N个数,找到区间和大于等于m的最小区间长度,没有输出0。
2
10 15
5 1 3 5 10 7 4 9 2 8
输出 2
5 11
1 2 3 4 5
输出 3
1 import java.util.Scanner;2
3 public classMain {4 static intcasen,n;5 static longm;6 static long[] a,sum;7 public static voidmain(String[] args) {8 Scanner cin = new Scanner(System.in);9 casen =cin.nextInt();10 while(casen-->0) {11 n =cin.nextInt();12 m =cin.nextLong();13 a = new long [n+10];14 sum = new long [n+10];15 for(int i=1;i<=n;i++) {16 a[i] =cin.nextLong();17 sum[i] = sum[i-1] +a[i];18 }19 int l = 1;20 int r = 1;21 int flag = 0;22 int ans = 0x3f3f3f3f;23 while(r<=n) {24 while(r<=n&&sum[r]-sum[l-1]=m) {28 flag = 1;29 ans = Math.min(ans, r-l+1);30 }31 l++;32 }33 if(flag==1)34 System.out.println(ans);35 else
36 System.out.println(0);37 }38 }39 }
二分图匹配:
一共有N个学生跟P门课程,一个学生可以任意选一 门或多门课,问是否达成:
1.每个学生选的都是不同的课(即不能有两个学生选同一门课)
2.每门课都有一个代表(即P门课都被成功选过)
输入为:
第一行一个T代表T组数据
P N(P课程数, N学生数)
接着P行:
第几行代表第几门课程,首先是一个数字k代表对这门课程感兴趣的同学的个数,接下来是k个对这门课程感兴趣同学的编号。
输出为:
若能满足上面两个要求这输出”YES”,否则为”NO”
注意:是课程匹配的学生,学生没课上没事.....
Input
2
3 3
3 1 2 3
2 1 2
1 1
3 3
2 1 3
2 1 3
1 1
Output
YES
NO
1 import java.util.Arrays;2 import java.util.Scanner;3
4 public classMain {5 static intn,p,k,casen;6 static int[][] link;7 static int[] match,used;8 static boolean find(intx) {9 for(int i=1;i<=n;i++) {10 if(link[x][i]==1&&used[i]==0) {11 used[i] = 1;12 if(match[i]==-1||find(match[i])) {13 match[i] =x;14 return true;15 }16 }17 }18 return false;19 }20 static inthungary() {21 int ans = 0;22 Arrays.fill(match, -1);23 for(int i=1;i<=p;i++) {24 Arrays.fill(used, 0);25 if(find(i))26 ans++;27 }28 returnans;29 }30 public static voidmain(String[] args) {31 Scanner cin = new Scanner(System.in);32 casen =cin.nextInt();33 while(casen-->0) {34 p =cin.nextInt();35 n =cin.nextInt();36 match = new int [310];37 used = new int [310];38 link = new int [310][310];39 for(int i=1;i<=p;i++) {40 int k =cin.nextInt();41 while(k-->0) {42 int x =cin.nextInt();43 link[i][x] = 1;44 }45 }46 int ans =hungary();47 if(ans==p)48 System.out.println("YES");49 else
50 System.out.println("NO");51 }52 }53 }
dfs搜索
给出你一个无向图,然后对其中的点去上色, 只能上黑色和白色,要求是黑色点不能相邻(白色可以相邻),问最多能上多少黑色的顶点。
1
6 8
1 2
1 3
2 4
2 5
3 4
3 6
4 6
5 6
Sample Output
3
1 4 5
1 import java.util.ArrayList;2 import java.util.Scanner;3
4 public classMain{5 static int[] vis,res;6 static intn,ans;7 static ArrayList [] v = new ArrayList[110];8 static void dfs(int pos,intsum) {9 if(pos==n+1) {10 if(sum>ans) {11 ans =sum;12 int cnt = 0;13 for(int i=1;i<=n;i++) {14 if(vis[i]==1)15 res[cnt++] =i;16 }17 }18 return;19 }20 int flag = 0;21 for(int i=0;i0) {38 n =cin.nextInt();39 ans = 0;40 res = new int [n+10];41 vis = new int [n+10];42 for(int i=0;i();44 int m =cin.nextInt();45 for(int i=0;i
05.21
错排
N个数,有M个错排的组合数
1 import java.util.Scanner;2
3 public classMain {4 static long [][] c = new long [30][30];5 static intn,m;6 static voidinit() {7 c[0][0] = 1;8 for(int i=1;i<=25;i++) {9 c[i][0] = 1;10 for(int j=1;j<=i;j++) {11 if(j<=i/2)12 c[i][j] = c[i-1][j]+c[i-1][j-1];13 else
14 c[i][j] = c[i][i-j];15 }16 }17 }18 static voidinit2() {19 c[0][0] = 1;20 for(int i=1;i<=25;i++) {21 c[i][0] = 1;22 c[i][i] = 1;23 for(int j=1;j0) {38 n =cin.nextInt();39 m =cin.nextInt();40 System.out.println(dp[m]*c[n][m]);41 }42 }43 }
kmp:
给定两个数组,问能不能再第一个数组中匹配得到第二个数组,如果可以,那么输出最早匹配的起始位置,否则输出-1
1 import java.util.Scanner;2
3 public classMain {4 static intn,m;5 static int[] s,t;6 static int[] next;7 static voidgetnext() {8 next[0] = -1;9 int i=0,j=-1;10 while(i
17 j =next[j];18 }19
20 }21 static intkmp() {22 int i=0,j=0;23 while(i
29 j =next[j];30 }31 if(j==m) {32 return i-m+1;33 }34 else
35 return -1;36 }37 public static voidmain(String[] args) {38 Scanner cin = new Scanner(System.in);39 int casen =cin.nextInt();40 while(casen-->0) {41 n =cin.nextInt();42 m =cin.nextInt();43 s = new int [n+10];44 t = new int [m+10];45 next = new int [m+10];46 for(int i=0;i
kmp求循环节:
字符串长度为N,循环节长度为N-next[N],
给一个字符串,问这个字符串是否能由另一个字符串重复R次得到,求R的最大值。
1 import java.util.Scanner;2
3 public classMain {4 static intn;5 static char[] s;6 static int[] next;7 static voidgetnext() {8 next[0] = -1;9 int i=0,j=-1;10 while(i
17 j =next[j];18 }19 }20 public static voidmain(String[] args) {21 Scanner cin = new Scanner(System.in);22 int ca = 1;23 while(cin.hasNext()) {24 String ss =cin.nextLine();25 if(ss.equals("."))26 break;27 n =ss.length();28 next = new int [n+10];29 s =ss.toCharArray();30 getnext();31
32 int len = n-next[n];33 if(n%len==0) {34 System.out.println(n/len);35 }else{36 System.out.println(1);37 }38 }39 }40 }
搜索
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
Sample Output
2
1
1 import java.util.Scanner;2
3 public classMain {4 static intk,n;5 static String [] s = new String[10];6 static int [] vish = new int[10];7 static int [] viss = new int[10];8 static char[][] a = new char[10][10];9 static int ans = 0;10 static void dfs(int x,intstep) {11 if(step>=k) {12 ans++;13 return;14 }15 for(int i=x;i
50 }51 }
05.22
LCA:
求树上两点最短距离
1 import java.util.Arrays;2 import java.util.Scanner;3 classnode{4 intto;5 intval;6 intnext;7 }8 public classMain {9 static intn,q;10 static int[] head,dis,depth;11 staticnode [] e;12 static int cnt = 0;13 static int[][] f;14 static void add(int x,int y,intw) {15 e[cnt].to =y;16 e[cnt].val =w;17 e[cnt].next =head[x];18 head[x] = cnt++;19 }20 static void dfs(int x,intfa) {21 f[x][0] =fa;22 for(int i=head[x];i!=-1;i=e[i].next) {23 int to =e[i].to;24 if(to!=fa) {25 dis[to] = dis[x]+e[i].val;26 depth[to] = depth[x] + 1;27 dfs(to, x);28 }29 }30 }31 static voidinit() {32 depth[1] = 1;33 dis[1] = 0;34 dfs(1, 0);35 //设fa[i][j]表示i结点的第2^j个祖先,显然有
36 for(int j=1;(1<>m;88
89 for(int i=0;i
05.23
树的直径
求树上相距最远两点的距离
1 import java.util.ArrayDeque;2 import java.util.Arrays;3 import java.util.Scanner;4 classnode{5 intto;6 intw;7 intnext;8 }9 public classMain {10 static node [] e = new node[100000];11 static int [] head = new int [10000];12 static int [] dis = new int [10000];13 static int [] vis = new int [10000];14 static int cnt = 0,ed,sum;15 static void add(int x,int y,intw) {16 e[cnt].to =y;17 e[cnt].w =w;18 e[cnt].next =head[x];19 head[x] = cnt++;20
21 }22 static void bfs(intx) {23 ArrayDeque q = new ArrayDeque();24 q.offer(x);25 Arrays.fill(vis, 0);26 Arrays.fill(dis, 0);27 vis[x] = 1;28 sum = 0;29 while(!q.isEmpty()) {30 int pos =q.poll();31 for(int i=head[pos];i!=-1;i=e[i].next) {32 int to =e[i].to;33 if(vis[to]==0) {34 vis[to] = 1;35 dis[to] = dis[pos] +e[i].w;36 if(sum
60 System.out.println(sum);61 }62 }
拓扑排序:
1 import java.util.ArrayDeque;2 import java.util.Arrays;3 import java.util.PriorityQueue;4 import java.util.Scanner;5 classnode{6 intto;7 intnex;8 }9 public classMain{10 static intn,m,cnt,t;11 staticnode [] e;12 static int [] head,in,ans;13 static void add(int x,inty) {14 e[cnt].to =y;15 e[cnt].nex =head[x];16 head[x] = cnt++;17 }18 static voidtopu() {19 PriorityQueueq = new PriorityQueue();20 for(int i=1;i<=n;i++) {21 if(in[i]==0)22 q.offer(i);23 }24 t = 0;25 while(!q.isEmpty()) {26 int pos =q.poll();27 ans[t++] =pos;28 for(int i=head[pos];i!=-1;i=e[i].nex){29 int to =e[i].to;30 in[to]--;31 if(in[to]==0)32 q.offer(to);33 }34 }35 }36 public static voidmain(String[] args) {37 Scanner cin = new Scanner(System.in);38 while(cin.hasNext()) {39 cnt = 0;40 t = 0;41 n =cin.nextInt();42 m =cin.nextInt();43 e = new node[m+10];44 for(int i=0;i
manacher
import java.util.Collection;
import java.util.PriorityQueue;
import java.util.Scanner;public classMain{staticString s,t;static int[] r;static int manacher(intn) {int cnt = 0;
t= "";
t+="$#";for(int i=0;i
t+=s.charAt(i);
t+="#";
}//System.out.println(t);
int pos = 0,rx = 0,ans = 1;
cnt=t.length();;for(int i=1;i
r[i]=(rx>i)?Math.min(r[2*pos-i], rx-i):1;while(i-r[i]>=0&&i+r[i]
r[i]++;if(rx
rx= i+r[i];
pos=i;
}if(ans
ans= r[i]-1;
}returnans;
}public static voidmain(String[] args) {
Scanner cin= new Scanner(System.in);while(cin.hasNext()) {
s=cin.next();if(s.equals("END"))break;
r= new int [1000000*2+10];
System.out.println(manacher(s.length()));
}
}
}
一些JAVA知识点:
import java.util.*;public classxx {static class cmp implements Comparator{
@Overridepublic intcompare(LLong o1, LLong o2) {return (int) (o2.val -o1.val);
}
}static List list = new ArrayList();static Queue qu = new LinkedList();static Deque quee = new LinkedList();static PriorityQueue que = new PriorityQueue();static Set set = new TreeSet();static Map> map = new TreeMap>();static class LLong implements Comparable{intx;longval;
String s;
@Overridepublic intcompareTo(LLong o) {if(this.x ==o.x)return (int) (this.val -o.val);else if(this.x >=o.x)return (int) (o.val - this.val);else
return (this.s).compareTo(o.s);
}
}public static voidmain(String[] args) {
Collections.sort(list,newcmp());
Collections.sort(list,new Comparator() {
@Overridepublic intcompare(LLong o1, LLong o2) {return (int) (o2.val-o1.val);
}
});
}
}
Input输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。Output对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。Sample Input
1
8 2
2 100 4
4 100 2
Sample Output
400
1 #include
2 #include
3 #include
4 #include
5 using namespacestd;6 int c[11000],w[11000],num[11000];7 int dp[11000];8 intm,n,tip;9 intcasen;10 void ZeroOnePack(int c, intw)11 {12 for(int v =n; v >=c; v--)13 {14 dp[v] = max(dp[v],dp[v-c]+w);15 }16 }17
18 void CompletePack(int c, intw)19 {20 for(int v = c; v <= n; v++)21 {22 dp[v] = max(dp[v],dp[v-c]+w);23 }24 }25
26 void MultiplePack(int c, int w, intnum)27 {28 if(c*num>=n)29 {30 CompletePack(c,w);31 }32 else
33 {34 int k = 1;35 while(k