0
点赞
收藏
分享

微信扫一扫

poj-2709

Ewall_熊猫 2023-05-23 阅读 112


141MS 
  Java 

 import java.util.Arrays; 

 import java.util.Comparator; 

 import java.util.Scanner; 



 public class Main{ 

private static final int BOTTLE_V = 50; 

private static final int V_TYPE_MAX = 12; 

private int mColorTypeNum; 

private int[] mColorRequireV; 

private int mGrayV; 

private Comparator mCmp; 



public void addRequireV(int V) { 

mColorRequireV[mColorTypeNum++] = V; 

} 



public void setGrayV(int V) { 

mGrayV = V; 

} 



public Main() { 

mColorRequireV = new int[V_TYPE_MAX]; 

mCmp = new reverseComparator(); 

reset(); 

} 



public class reverseComparator implements Comparator<Integer> { 

@Override 

public int compare(Integer p1, Integer p2) { 

return p2 - p1; 

} 

} 



public void solve() { 

Arrays.sort(mColorRequireV, 0, mColorTypeNum); 

int maxV = mColorRequireV[mColorTypeNum-1]; 

Integer colorLeft[] = new Integer[V_TYPE_MAX]; 

int i = 0; 

for (; BOTTLE_V*i < maxV; i++) { 

} 

int minBottleWithoutGray = i; 



// System.out.println(minBottleWithoutGray); 



for (i = 0; i < mColorTypeNum; i++) { 

colorLeft[i] = minBottleWithoutGray*BOTTLE_V - mColorRequireV[i]; 

// System.out.println(colorLeft[i]); 

} 



Arrays.sort(colorLeft, 0, mColorTypeNum, mCmp); 



int gray_V = mGrayV; 



while(true) { 

// System.out.println(gray_V); 

if (gray_V <= 0) { 

break; 

} 

if (colorLeft[2] <= 0) { // no enough 3 colors to mix gray, has add bottle  

minBottleWithoutGray++; 

for (i = 0; i < mColorTypeNum; i++) { 

colorLeft[i] += BOTTLE_V; 

// System.out.println(colorLeft[i]); 

} 
  

} 

// can mix colorLeft[2] V gray 

 

int thisTimeGrayV; 

if (mColorTypeNum > 3 && colorLeft[3] > 0) { 

 
thisTimeGrayV = colorLeft[2] - colorLeft[3] + 1; 

} else { 

thisTimeGrayV = colorLeft[2]; 

} 

// System.out.println(thisTimeGrayV); 

gray_V -= thisTimeGrayV; 

colorLeft[0] -= thisTimeGrayV; 

colorLeft[1] -= thisTimeGrayV; 

colorLeft[2] -= thisTimeGrayV; 

Arrays.sort(colorLeft, 0, mColorTypeNum, mCmp); 

} 



System.out.println(minBottleWithoutGray); 

reset(); 

} 



public void reset() { 

mColorTypeNum = 0; 

mGrayV = 0; 

} 



public static void main(String args[]) { 

Main solver = new Main(); 

Scanner scanner = new Scanner(System.in); 

while(true) { 

int colorTypeNum = scanner.nextInt(); 

if (colorTypeNum == 0) { 

return; 

} 

for (int i = 0; i < colorTypeNum; i++) { 

solver.addRequireV(scanner.nextInt()); 

} 

solver.setGrayV(scanner.nextInt()); 

solver.solve(); 
  

} 

}  
}
//3552K 141MS Java

算是个贪心水题,不过有个很重要的细节:

思路大致如下:

首先,先不考虑gray,先看其他普通颜色最少需要多少套kit, 只要找一个i使得i*50 是大于 (这些颜色中数量最多的颜色数量)的最小值即可,

i 就是能满足普通颜色数量要求的最少kit数量。

在得到i以后,就可以得到每种颜色还剩多少额外的量来得到gray的量,直接用i*50减去每种颜色的需求量即可,

贪心的选择就是,先紧着额外量最多的3种颜色来得到gray色,

这里有个重要的细节,比如有4种颜色ABCD,额外量从大到小为 V(A)>=V(B)>=V(C)>=V(D)

那么就要先从ABC三色选取一定量V来得到gray,最初想以为V取C即可,后来发现不应该只这样,

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

假设一个V1<V, 那么很有可能会有这样的情景:

在ABC都取了V1以后,额外量的大小关系就变成了 V(D)>=V(A)-V1>=V(B)-V1>=V(C)-V1,

这种情况下,按照贪心选择,就不能再从ABC中选取来配gray了,而应该从DAB中选取来配gray了,

所以,理论上讲,一应该是以1ml为单位来进行贪心选择,因为每从三种颜色各取1ml来配gray以后,颜色之间的剩余量的大小关系就有可能已经变化了,

这个思想要牢记,也反映了计算机的步进式运行.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

所以应该每配1ml的gray,就对颜色进行重排,然后选取新的前3多的颜色。

不过如果真这么搞,那么铁定TLE,如果要求1000gray,那要搞10000此重排,

因此不能以1ml为单位进行上面的操作,假设现在V(A)>=V(B)>=V(C)>=V(D)

那么可以确定,最多从ABC取 V(C)-V(D) ml来配gray, 颜色之间的大小关系是不会变化的,

因此,可以每次取 V(C)-V(D) + 1 来配gray(前提是最少4种颜色,以及 V(D)是大于0的),

还会遇到V(C)(第三多的颜色数量)已经为0,这种情况下,必须要增加kit数量了,

每种颜色的量都会增加50,

按照上面这个过程循环,直到第一次配出了>= gray要求 的gray数量.


举报

相关推荐

HDU 2709 Sumsets

poj 2472

北大POJ

POJ 2503

poj 1691

POJ 3123

POJ 1611

POJ - 2456

0 条评论