首页 > 其他分享 >HDOJ1205 吃糖果

HDOJ1205 吃糖果

时间:2023-02-20 10:32:18浏览次数:58  
标签:java int max sum HDOJ1205 maxn 糖果


题目链接:​​http://acm.hdu.edu.cn/showproblem.php?pid=1205​

方法1:


如果最大堆-次大堆<=1,那么问题肯定有解:
我们可以从最大和次大里面每次拿一个,然后等他们和第三大堆相等的时候。
每次从三堆里面各拿一个,等他们和第四大堆相等的时候。
每次从四堆里面各拿一个,这样一直拿完所有堆。
问题变成了能不能使得最大堆-次大堆<=1,所以之前我们会从次大堆之外的那些堆里面取。
来让最大堆减少,如果能减到:最大堆-次大堆<=1,那么原问题有解。
能否减到要看:
sum - max - max2 >= max - max2 - 1
是否成立,其中sum为总和,max为最大堆,max2为次大。
整理得:
2 * max - sum <= 1


方法2:


鸽巢原理

1.把某种糖果看做隔板,如果某种糖果有n个,那么就有n+1块区域,至少需要n-1块其他种糖果才能使得所有隔板不挨在一块..也就是说能吃完这种糖果.至少需要其他种类糖果n-1块..(鸽巢原理)

2.数量最多的糖果(隔板)可以构造最多的空间,如果这种糖果有maxn个....那么需要maxn-1个其他种糖果.对于某种数量少于maxn的糖果来说,可以在原本数量最多的糖果构造的隔板上"加厚"原有的隔板...,那么这"某种糖果"就销声匿迹了.....

考虑极端情况.如果某种糖果无法在这maxn+1的空间内构造出符合条件的序列,那么这种糖果至少要有maxn+1+1个(考虑只有两种糖果的情况)...(鸽巢原理)...但是这与数量最多的那种糖果只有maxn个矛盾.....(maxn+1+1>maxn 这不等式不难理解吧....).

刚开始也是想到第一种方法,但是没考虑的周全,结果WA了。


后来才找到第二种方法,也WA了,原因是总和sum大于int 的最大值,需要使用Long。


其实两种方法的过程都是一样的,只是思想不同。


另外,题目总写明了使用scanf,对应java,就应该使用streamTokenizer了


下面代码:


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

//至少需要max-1个其他糖果(其他糖果是sum-max个)
public class Main{
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();
int cases = (int) in.nval;
while (cases-- > 0) {
in.nextToken();
int n = (int) in.nval;
int max = 0;// 最大数
long sum = 0;// 糖果总数(一定要使用long!!!!!!!)
for (int i = 0; i < n; i++) {
in.nextToken();
int t = (int) in.nval;
sum += t;
if (max < t) {
max = t;
}
}
// if (sum - max >= max - 1) {//也OK(隔板)
if (2*max-sum<=1) {//sum-max-max2>=max-max2-1(max2为次大)
out.println("Yes");
out.flush();
} else {
out.println("No");
out.flush();
}
}
}
}



标签:java,int,max,sum,HDOJ1205,maxn,糖果
From: https://blog.51cto.com/u_15741949/6067742

相关文章