直接找最大和最小的数取差值即可。
1 2 3 4 5 6 7 8 9 10 11 12 int n; void solve (void ) { cin>>n; int minn=INT_MAX,maxx=0 ; for (int i=1 ,x;i<=n;i++){ cin>>x; minn=min (minn,x); maxx=max (maxx,x); } cout<<maxx-minn<<endl; }
分类讨论一下,很显然,我们直接第一行逐个取格子,第一行是每个格子都可以提供2 2 2 的新对角线贡献的。k k k 小等于于2 n 2n 2 n 的时候,直接输出⌈ k / 2 ⌉ \lceil k/2\rceil ⌈ k / 2 ⌉ 即可。如果k ≥ 2 n k\geq 2n k ≥ 2 n ,也就是说第一行的格子提供的贡献不够了,再来看最后一行,最后一行除了第一个和第二个格子,每个也可以提供2 n 2n 2 n 的贡献,因此在k ≤ 2 ( n + n − 2 ) k\leq 2(n+n-2) k ≤ 2 ( n + n − 2 ) 的情况下,我们也可以同理输出⌊ k / 2 ⌋ \lfloor k/2\rfloor ⌊ k / 2 ⌋ 。然后剩下就只有两种情况,4 n − 4 < n ≤ 4 n − 2 4n-4<n\leq 4n-2 4 n − 4 < n ≤ 4 n − 2 ,这两种情况,我们把最后一行剩下两个格子取了就行。
(这里我第一次wa了,后面乱改改过了,发现是因为cout
输出double
类型会出现科学计数法的问题,这里ceil
本来是double
类型的,要强制转成long long
或者其他整型。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 void solve (void ) { ll n,k; cin>>n>>k; if (k<=2 *n){ cout<<(ll)(ceil ((double )k/2 ))<<endl; return ; } ll ans=n; k-=2 *n; if (k<=2 *(n-2 )){ cout<<(ll)(ans+ceil ((double )k/2 ))<<endl; return ; } k-=2 *(n-2 ); ans+=n-2 ; cout<<(ll)(ans+k)<<endl; }
这题有点像那个经典的赌场问题,就是在本金无限大的情况下,不断赌博是必赢的,因为只要每一次下的赌注足够大,大到赢了一次的奖励能大于前面的损失,即使不断输,只要赢一次,就能翻本。比如假设输赢的概率五五开,第一次赌1块,输了,那第二次赌2块,赢了就能赢4块,翻本。如果还输,就赌8块,以此类推。
所以只需要1 1 1 到x x x 次,假设一直输,下的赌注每次都使得如果赢的奖金能翻本并且多一点即可。如果没赌到x x x 次,本金就不够了,那就必输了,前面的1 1 1 到x x x 次,因为我们下的赌注是赢一次能翻本的,所以只要能赢一次,就能继续从头开始继续赢。但是这里我们要求最坏情况下,如果赌到x x x 次都一直输,接下来就是必胜局了,直接赌上所有剩余本金,如果这次赢的能覆盖之前的所有损失,就是必赢的,如果不能,就是必输的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ll k,x,a; void solve (void ) { cin>>k>>x>>a; ll now=a; debug (a); for (int i=0 ;i<x;i++){ ll y=max (1LL ,(ll)floor ((double )(a-now)/(double )(k-1 ))+1 ); now-=y; debug (i,y,now); if (now<=0 ){ cout<<"NO" <<endl; return ; } } now*=k; if (now>a) cout<<"YES" <<endl; else cout<<"NO" <<endl; }
很显然最终集合的最大的规模,是这棵树的叶子节点数。
既然是树上问题,考虑一下dp,每个节点u
的子树中,设dp[u]
为节点u
及其子树中的满足不存在任何直接祖先关系的集合的大小,同时要注意,单个节点占据路口也是可以的。假设u
节点有一堆儿子v1,v2,...,vm
,可以得到递推方程:
d p [ u ] = ∏ ( 1 + d p [ v ] ) dp[u]=\prod(1+dp[v])
d p [ u ] = ∏ ( 1 + d p [ v ] )
那直接取模就可以了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 int n;vector<int > G[maxn+5 ]; ll dp[maxn+5 ]; void dfs (int u,int fa) { for (int v: G[u]) if (v!=fa){ dfs (v,u); dp[u]*=(dp[v]+1 ); dp[u]%=mod; } } void prepare () { for (int i=0 ;i<=n;i++){ dp[i]=1 ; G[i].clear (); } } void solve (void ) { cin>>n; prepare (); vector<int > in (n+1 ,0 ) ; for (int i=1 ,u,v;i<n;i++){ cin>>u>>v; G[u].push_back (v); G[v].push_back (u); } dfs (1 ,0 ); ll ans=0 ; for (int i=0 ;i<=n;i++) ans+=dp[i],ans%=mod; cout<<ans<<endl; }