HDU5835 Danganronpa(簡單推理)
鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5835
題目
Time Limit: 1000MS Memory Limit: 65536KB
Description
Chisa Yukizome works as a teacher in the school. She prepares many gifts, which consist of
Each table will be prepared for a mysterious gift and an ordinary gift.
In order to reflect the Chisa Yukizome’s generosity, the kinds of the ordinary gift on the adjacent table must be different.
There are no limits for the mysterious gift.
The gift must be placed continuously.
She wants to know how many students can get gifts in accordance with her idea at most (Suppose the number of students are infinite). As the most important people of her, you are easy to solve it, aren’t you?
Input
The first line of input contains an integer
Each case contains one integer
Output
For each test case, output one line containing “Case #x: y” (without quotes) , where x is the test case number (starting from 1) and y is the answer of Chiaki Nanami’s question.
Sample Input
1
2
3 2
Sample Output
Case #1: 2
題意
有n種禮物,第i個有
分析
首先,貪心法模擬能過,但是時空複雜度就不理想了。
其實這題還可以用簡單的推理完成,一個判斷即可,0ms過題。下面給出思想。
首先,我們要去想辦法將問題分成幾個條件來轉化後考慮。
情況1:我們考慮有無數量“絕對大”的禮物,絕對大即該種禮物的總數比其他種類的所有禮物的總數還要多。那麼,能否發給多少人就與這個絕對大的禮物有關。先分配普通禮物:我們把其他禮物按間隔爲1擺放,然後讓絕對大的禮物去插空。然後多餘的去填補神祕禮物,如果神祕禮物也能填補完,那麼總數就爲其他禮物數*2+1;如果填補不完,就從普通禮物後面截取然後往神祕禮物填,直到神祕和普通數量相同,總數爲(其他禮物+總數最大的禮物個數)/2。如果不懂請見代碼。
情況2:沒有“絕對大”禮物,那麼一定可以保證所有禮物排列後不存在相鄰相同項(有興趣的可以想辦法證明)。那麼總數就爲總禮物數/2。
源碼
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
#include<sstream>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<utility>
#include<sstream>
#define mem0(x) memset(x,0,sizeof x)
#define mem1(x) memset(x,-1,sizeof x)
#define dbug cout<<"here"<<endl;
//#define LOCAL
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6+10;
const int MOD = 1000000007;
int a[20];
int main(){
#ifdef LOCAL
freopen("C:\\Users\\asus-z\\Desktop\\input.txt","r",stdin);
freopen("C:\\Users\\asus-z\\Desktop\\output.txt","w",stdout);
#endif
int t;
scanf("%d", &t);
int n;
int kase = 0;
while(t--){
scanf("%d", &n);
ll sum = 0;
for(int i = 0; i < n; ++i){
scanf("%d", &a[i]);
sum += a[i];
}
sort(a, a+n);
int maxx = a[n-1];
sum -= maxx;
printf("Case #%d: ", ++kase);
if(maxx >= (((sum+1)+sum) + (sum+1)))
cout << sum*2+1 << endl;
else
cout << (sum+maxx)/2 << endl;
}
return 0;
}