Advertisement
qwerty787788

TVShow problem

Oct 30th, 2013
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.70 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. public class TV {
  5.  
  6.     class TVShow {
  7.         int id;
  8.         int a, b, type;
  9.  
  10.         TVShow(int id, int type, int a, int b) {
  11.             this.id = id;
  12.             this.a = a;
  13.             this.b = b;
  14.             this.type = type;
  15.         }
  16.     }
  17.  
  18.     int[] getPartitionCost(ArrayList<TVShow> a) {
  19.         int n = a.size();
  20.         int[][] dp = new int[n + 1][n + 1];
  21.         for (int i = 0; i < n + 1; i++)
  22.             Arrays.fill(dp[i], Integer.MIN_VALUE / 3);
  23.         dp[0][0] = 0;
  24.         for (int i = 0; i < n; i++)
  25.             for (int nowGroups = 0; nowGroups <= n; nowGroups++)
  26.                 if (dp[nowGroups][i] != Integer.MIN_VALUE / 3) {
  27.                     dp[nowGroups][i + 1] = Math.max(dp[nowGroups][i + 1],
  28.                             dp[nowGroups][i]);
  29.                     dp[nowGroups][i + 1] = Math.max(dp[nowGroups][i + 1],
  30.                             dp[nowGroups][i] + a.get(i).a);
  31.                     dp[nowGroups + 1][i + 1] = Math.max(
  32.                             dp[nowGroups + 1][i + 1],
  33.                             dp[nowGroups][i] + a.get(i).b);
  34.                 }
  35.         int[] res = new int[n + 1];
  36.         for (int i = 0; i <= n; i++)
  37.             res[i] = dp[i][n];
  38.         res[0] = 0;
  39.         return res;
  40.     }
  41.  
  42.     int[] getAnsForSomeType(ArrayList<TVShow> a, int needGroups) {
  43.         if (needGroups == 0) {
  44.             return new int[] {};
  45.         }
  46.         int n = a.size();
  47.         int[][] dp = new int[n + 1][n + 1];
  48.         int[][] lastTypeDp = new int[n + 1][n + 1];
  49.         // 0 = not used
  50.         // 1 = +a
  51.         // 2 = +b
  52.         for (int i = 0; i < n + 1; i++)
  53.             Arrays.fill(dp[i], Integer.MIN_VALUE / 3);
  54.         dp[0][0] = 0;
  55.         for (int i = 0; i < n; i++)
  56.             for (int nowGroups = 0; nowGroups <= n; nowGroups++)
  57.                 if (dp[nowGroups][i] != Integer.MIN_VALUE / 3) {
  58.                     if (dp[nowGroups][i] > dp[nowGroups][i + 1]) {
  59.                         dp[nowGroups][i + 1] = Math.max(dp[nowGroups][i + 1],
  60.                                 dp[nowGroups][i]);
  61.                         lastTypeDp[nowGroups][i + 1] = 0;
  62.                     }
  63.                     if (dp[nowGroups][i] + a.get(i).a > dp[nowGroups][i + 1]) {
  64.                         dp[nowGroups][i + 1] = Math.max(dp[nowGroups][i + 1],
  65.                                 dp[nowGroups][i] + a.get(i).a);
  66.                         lastTypeDp[nowGroups][i + 1] = 1;
  67.                     }
  68.                     if (dp[nowGroups][i] + a.get(i).b > dp[nowGroups + 1][i + 1]) {
  69.                         dp[nowGroups + 1][i + 1] = Math.max(
  70.                                 dp[nowGroups + 1][i + 1],
  71.                                 dp[nowGroups][i] + a.get(i).b);
  72.                         lastTypeDp[nowGroups + 1][i + 1] = 2;
  73.                     }
  74.                 }
  75.         ArrayList<Integer> usedAsA = new ArrayList<>();
  76.         ArrayList<Integer> usedAsB = new ArrayList<>();
  77.         for (int i = n; i > 0; i--) {
  78.             if (lastTypeDp[needGroups][i] == 0) {
  79.                 // nothing to do here
  80.             } else {
  81.                 if (lastTypeDp[needGroups][i] == 1) {
  82.                     usedAsA.add(a.get(i - 1).id);
  83.                 } else {
  84.                     usedAsB.add(a.get(i - 1).id);
  85.                     needGroups--;
  86.                 }
  87.             }
  88.         }
  89.         int[] res = new int[usedAsA.size() + usedAsB.size()];
  90.         for (int i = 0; i < usedAsB.size(); i++) {
  91.             res[i] = usedAsB.get(i);
  92.         }
  93.         for (int i = 0; i < usedAsA.size(); i++) {
  94.             res[i + usedAsB.size()] = usedAsA.get(i);
  95.         }
  96.         return res;
  97.     }
  98.  
  99.     void printAns(int biggestGroup) {
  100.         int[][] dp = new int[n + 1][n + 1];
  101.         for (int i = 0; i <= n; i++)
  102.             Arrays.fill(dp[i], Integer.MIN_VALUE / 3);
  103.         dp[0][0] = 0;
  104.         for (int type = 0; type < n; type++) {
  105.             for (int wasCount = 0; wasCount <= n; wasCount++)
  106.                 if (dp[type][wasCount] != Integer.MIN_VALUE / 3) {
  107.                     for (int newGroupSize = 0; newGroupSize < Math.min(
  108.                             biggestGroup + 1, partitionCost[type].length); newGroupSize++) {
  109.                         dp[type + 1][wasCount + newGroupSize] = Math.max(
  110.                                 dp[type + 1][wasCount + newGroupSize],
  111.                                 dp[type][wasCount]
  112.                                         + partitionCost[type][newGroupSize]);
  113.                     }
  114.                 }
  115.         }
  116.         int best = 0, bestTotal = -1;
  117.         for (int totalGroupsCount = biggestGroup * 2 - 1; totalGroupsCount <= n; totalGroupsCount++) {
  118.             int cost = dp[n][totalGroupsCount];
  119.             if (cost > best) {
  120.                 best = cost;
  121.                 bestTotal = totalGroupsCount;
  122.             }
  123.         }
  124.         int[] needSomeType = new int[n];
  125.         for (int type = n; type > 0; type--) {
  126.             for (int newGroupSize = 0; newGroupSize < Math.min(
  127.                     biggestGroup + 1, partitionCost[type - 1].length); newGroupSize++) {
  128.                 if (bestTotal - newGroupSize >= 0) {
  129.                     if (dp[type - 1][bestTotal - newGroupSize]
  130.                             + partitionCost[type - 1][newGroupSize] == dp[type][bestTotal]) {
  131.                         needSomeType[type - 1] = newGroupSize;
  132.                         bestTotal -= newGroupSize;
  133.                         break;
  134.                     }
  135.                 }
  136.             }
  137.         }
  138.         int[][] resultForSomeType = new int[n][];
  139.         for (int i = 0; i < n; i++) {
  140.             resultForSomeType[i] = getAnsForSomeType(ofSomeType[i],
  141.                     needSomeType[i]);
  142.         }
  143.         ArrayList<Integer>[] groups = new ArrayList[biggestGroup];
  144.         for (int i = 0; i < groups.length; i++)
  145.             groups[i] = new ArrayList<>();
  146.         int iter = 0;
  147.         for (int type = 0; type < n; type++) {
  148.             if (needSomeType[type] == biggestGroup) {
  149.                 for (int j = 0; j < needSomeType[type]; j++) {
  150.                     groups[j].add(resultForSomeType[type][j]);
  151.                 }
  152.                 for (int j = needSomeType[type]; j < resultForSomeType[type].length; j++)
  153.                     groups[0].add(resultForSomeType[type][j]);
  154.             }
  155.         }
  156.         for (int type = 0; type < n; type++) {
  157.             if (needSomeType[type] != biggestGroup) {
  158.                 int fIter = iter;
  159.                 for (int j = 0; j < needSomeType[type]; j++) {
  160.                     groups[iter].add(resultForSomeType[type][j]);
  161.                     iter++;
  162.                     if (iter >= biggestGroup - 1)
  163.                         iter = 0;
  164.                 }
  165.                 for (int j = needSomeType[type]; j < resultForSomeType[type].length; j++)
  166.                     groups[fIter].add(resultForSomeType[type][j]);
  167.             }
  168.         }
  169.         ArrayList<Integer> result = new ArrayList<>();
  170.         for (int group = 0; group < groups.length; group++)
  171.             for (int x : groups[group])
  172.                 result.add(x);
  173.         out.println(result.size());
  174.         for (int i = 0; i < result.size(); i++) {
  175.             out.print((result.get(i)) + " ");
  176.         }
  177.         out.println();
  178.     }
  179.  
  180.     int n;
  181.     int[][] partitionCost;
  182.     ArrayList<TVShow>[] ofSomeType;
  183.  
  184.     void solve() {
  185.         n = in.nextInt();
  186.         TVShow[] a = new TVShow[n];
  187.         for (int i = 0; i < n; i++) {
  188.             a[i] = new TVShow(i + 1, in.nextInt() - 1, in.nextInt(),
  189.                     in.nextInt());
  190.         }
  191.         ofSomeType = new ArrayList[n];
  192.         for (int i = 0; i < n; i++) {
  193.             ofSomeType[i] = new ArrayList<>();
  194.         }
  195.         for (int i = 0; i < n; i++) {
  196.             ofSomeType[a[i].type].add(a[i]);
  197.         }
  198.         partitionCost = new int[n][];
  199.         for (int i = 0; i < n; i++) {
  200.             partitionCost[i] = getPartitionCost(ofSomeType[i]);
  201.         }
  202.         int bestAns = 0;
  203.         int bestBiggestGroupSize = -1;
  204.         for (int biggestGroup = 1; biggestGroup <= n; biggestGroup++) {
  205.             int[][] dp = new int[n + 1][n + 1];
  206.             for (int i = 0; i <= n; i++)
  207.                 Arrays.fill(dp[i], Integer.MIN_VALUE / 3);
  208.             dp[0][0] = 0;
  209.             for (int type = 0; type < n; type++) {
  210.                 for (int wasCount = 0; wasCount <= n; wasCount++)
  211.                     if (dp[type][wasCount] != Integer.MIN_VALUE / 3) {
  212.                         for (int newGroupSize = 0; newGroupSize < Math.min(
  213.                                 biggestGroup + 1, partitionCost[type].length); newGroupSize++) {
  214.                             dp[type + 1][wasCount + newGroupSize] = Math
  215.                                     .max(dp[type + 1][wasCount + newGroupSize],
  216.                                             dp[type][wasCount]
  217.                                                     + partitionCost[type][newGroupSize]);
  218.                         }
  219.                     }
  220.             }
  221.             for (int totalGroupsCount = biggestGroup * 2 - 1; totalGroupsCount <= n; totalGroupsCount++) {
  222.                 int cost = dp[n][totalGroupsCount];
  223.                 if (cost > bestAns) {
  224.                     bestAns = cost;
  225.                     bestBiggestGroupSize = biggestGroup;
  226.                 }
  227.             }
  228.         }
  229.         if (bestAns == 0) {
  230.             out.println("0 0");
  231.             return;
  232.         }
  233.         out.print(bestAns + " ");
  234.         printAns(bestBiggestGroupSize);
  235.     }
  236.  
  237.     InputReader in;
  238.     PrintWriter out;
  239.  
  240.     void runIO() {
  241.         in = new InputReader(System.in);
  242.         out = new PrintWriter(System.out);
  243.  
  244.         solve();
  245.  
  246.         out.close();
  247.     }
  248.  
  249.     void run() {
  250.         in = new InputReader(new File("input.txt"));
  251.         try {
  252.             out = new PrintWriter(new File("output.txt"));
  253.         } catch (FileNotFoundException e) {
  254.             e.printStackTrace();
  255.         }
  256.  
  257.         solve();
  258.  
  259.         out.close();
  260.     }
  261.  
  262.     public static void main(String[] args) {
  263.         new TV().runIO();
  264.     }
  265.  
  266.     class InputReader {
  267.         BufferedReader bf;
  268.         StringTokenizer st;
  269.  
  270.         InputReader(File f) {
  271.             try {
  272.                 bf = new BufferedReader(new FileReader(f));
  273.             } catch (FileNotFoundException e) {
  274.                 e.printStackTrace();
  275.             }
  276.         }
  277.  
  278.         InputReader(InputStream s) {
  279.             bf = new BufferedReader(new InputStreamReader(s));
  280.         }
  281.  
  282.         String next() {
  283.             while (st == null || !st.hasMoreElements()) {
  284.                 String s;
  285.                 try {
  286.                     s = bf.readLine();
  287.                 } catch (IOException e) {
  288.                     return null;
  289.                 }
  290.                 if (s == null)
  291.                     return null;
  292.                 st = new StringTokenizer(s);
  293.             }
  294.             return st.nextToken();
  295.         }
  296.  
  297.         int nextInt() {
  298.             return Integer.parseInt(next());
  299.         }
  300.  
  301.         long nextLong() {
  302.             return Long.parseLong(next());
  303.         }
  304.  
  305.         double nextDouble() {
  306.             return Double.parseDouble(next());
  307.         }
  308.  
  309.         boolean hasMoreElements() {
  310.             while (!st.hasMoreElements()) {
  311.                 String s;
  312.                 try {
  313.                     s = bf.readLine();
  314.                 } catch (IOException e) {
  315.                     return false;
  316.                 }
  317.                 if (s == null)
  318.                     return false;
  319.                 st = new StringTokenizer(s);
  320.             }
  321.             return true;
  322.         }
  323.     }
  324. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement