usaco/ 1.3 milk/barn1

来源:互联网 发布:matlab 全局优化 编辑:程序博客网 时间:2024/05/18 11:02
package chapter1_3;/* ID: chicc991 LANG: JAVA TASK: milk */import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.PrintWriter;import java.util.Scanner;import java.util.TreeSet;public class milk{private Scanner sc;private PrintWriter out;private TreeSet<milker> arr;public static void main(String[] args) throws Exception{milk main = new milk();}public milk() throws Exception{sc = new Scanner(new FileReader(new File("data/milk.in")));out = new PrintWriter(new BufferedWriter(new FileWriter("data/milk.out")));while (sc.hasNext()) {double n = sc.nextDouble();int m = sc.nextInt();if (n == 0 || m == 0) {out.println(0);out.close();System.exit(0);}arr = new TreeSet<milker>();for (int i = 0; i < m; i++)arr.add(new milker(sc.nextDouble(), sc.nextDouble()));double sum = 0;milker mm = null;for (milker mi:arr) {n -= mi.count;if (n > 0)sum += mi.cost();else {mm=mi;break;}}sum += mm.price * (n + mm.count);out.println((int) sum);}out.close();sc.close();}}class milker implements Comparable<milker>{public double price;public double count;public milker(double price, double count){this.price = price;this.count = count;}@Overridepublic int compareTo(milker o){if (this.price >= o.price)return 1;elsereturn -1;}public double cost(){return price * count;}}

简单的贪心策略。注意如果用数组读入在排序会超时,可以直接用红黑树插入。

特殊解法:因为单价的范围为(0-1000)且为整数,所以可以开一个1001的数组,下标为单价,存储的值为数量。

package 优化;/* ID: chicc991 LANG: JAVA TASK: milk */import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.PrintWriter;import java.util.Scanner;public class milk{public static void main(String[] args) throws Exception{Scanner sc = new Scanner(new FileReader(new File("data/milk.in")));PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("data/milk.out")));while (sc.hasNext()) {double n = sc.nextDouble();int m = sc.nextInt();if (n == 0 || m == 0) {out.println(0);out.close();System.exit(0);}int[] a = new int[1001];for (int i = 0; i < m; i++)a[sc.nextInt()] += sc.nextInt();int sum = 0;int j = 0;for (int i = 0; i < 1001; i++) {n -= a[i];if (n > 0)sum += i * a[i];else {j = i;break;}}sum += (n + a[j]) * j;out.println(sum);}out.close();}}


barn1

package chapter1_3;/* ID: chicc991 LANG: JAVA TASK: barn1 */import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.PrintWriter;import java.util.PriorityQueue;import java.util.Scanner;public class barn1{private Scanner sc;private PrintWriter out;private PriorityQueue<zeroSet> que;public static void main(String[] args) throws Exception{barn1 main = new barn1();}public barn1() throws Exception{sc = new Scanner(new FileReader(new File("data/barn1.in")));out = new PrintWriter(new BufferedWriter(new FileWriter("data/barn1.out")));while (sc.hasNext()) {int m = sc.nextInt();int s = sc.nextInt();int c = sc.nextInt();int[] a = new int[s + 1];for (int i = 0; i < c; i++)a[sc.nextInt()] = 1;int i = 0;int j = s;while (a[i] == 0 && i < s)i++;while (a[j] == 0 && j > 0)j--;if (m != 1) {que = new PriorityQueue<zeroSet>(m - 1);int k = i;int l = i;int line = 0;while (k <= j) {if (a[k++] == 1) {line = k - l - 1;l = k;if (line > 0) {zeroSet zt = new zeroSet(line);if (que.size() == m - 1) {if (zt.compareTo(que.peek()) > 0) {que.poll();que.offer(zt);}} elseque.offer(zt);}continue;}while (a[k] == 0)k++;}int sum = 0;for (zeroSet zt : que)sum += zt.dis;out.println(j - i + 1 - sum);} else {out.println(j - i + 1);}}out.close();}class zeroSet implements Comparable<zeroSet>{public int dis;public zeroSet(int dis){this.dis = dis;}@Overridepublic int compareTo(zeroSet o){return this.dis - o.dis;}}}
长度最短,木板一定全用上。只需要找出m-1个最长的连续0,将他们去掉即可。构造大小为m-1的小顶堆。
/* ID: chicc991 LANG: JAVA TASK: barn1 */import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.PrintWriter;import java.util.ArrayList;import java.util.Collections;import java.util.Scanner;public class barn1{private Scanner sc;private PrintWriter out;private ArrayList<Integer> arr;public static void main(String[] args) throws Exception{barn1 main = new barn1();}public barn1() throws Exception{sc = new Scanner(new FileReader(new File("data/barn1.in")));out = new PrintWriter(new BufferedWriter(new FileWriter("data/barn1.out")));while (sc.hasNext()) {int m = sc.nextInt();int s = sc.nextInt();int c = sc.nextInt();arr = new ArrayList<Integer>(c + 1);arr.add(0);for (int i = 0; i < c; i++)arr.add(sc.nextInt());Collections.sort(arr);int[][] f = new int[m + 1][c + 1];for (int i = 0; i <= c; i++)f[1][i] = arr.get(i) - arr.get(1) + 1;for (int i = 0; i <= m; i++)f[i][1] = 1;for (int i = 2; i <= m; i++)for (int j = 2; j <= c; j++)f[i][j] = Math.min(f[i - 1][j - 1] + 1,f[i][j - 1] + arr.get(j) - arr.get(j - 1));out.println(f[m][c]);}out.close();sc.close();}}

以上为动态规划解法。

构建最优子结构:

f[i][j] = Math.min(f[i - 1][j - 1] + 1,f[i][j - 1] + arr.get(j) - arr.get(j - 1));
其中f[i][j]表示i块木板覆盖j头牛需要的最短长度,其值为i-1块木板覆盖j-1头牛后再用一块木板覆盖一头牛,或者延长一块木板到第j头牛所在牛栏,取2者的较小值

初始条件

(1)只有1块木板时,最小长度为第j头牛所在牛栏减去第一头牛所在牛栏

(2)只有1头牛时,最小长度为1

0 0
原创粉丝点击