P7137 [THUPC 2021 初赛] 切切糕

Solution

这题 没什么区别。

\(f_{i,j}\) 表示切了 \(i\) 个蛋糕,Tinytree 使用了 \(j\) 次“优先选糕权”时他能拿到的最多蛋糕。那么有 \(f_{i,j}=\max(f_{i-1,j-1}+a_i-t,f_{i-1,j}+t),0 \le t \le \frac{a_i}{2}\)。但因为 Kiana 希望 Tinytree 获得的蛋糕尽可能的小,所以当 \(f_{i-1,j-1}+a_i-t=f_{i-1,j}+t\),即 \(t=\frac{a_i+f_{i-1,j}-f_{i-1,j-1}}{2}\)\(f_{i,j}\) 最小,为 \(\frac{a_i+f_{i-1,j}+f_{i-1,j-1}}{2}\)

蛋糕的顺序应该从大到小枚举,可以贪心的想,将“优先选糕权”用在大蛋糕上肯定比用在小蛋糕上优。

但此时会出现一个问题:\(t\) 可能会小于 \(0\),因此要跟 \(f_{i-1,j}\)\(\max\)

Code

#include<bits/stdc++.h>
#define IOS cin.tie(0),cout.tie(0),ios::sync_with_stdio(0)
#define ll long long
#define db double
#define pb push_back
#define eb emplace_back
#define MS(x,y) memset(x,y,sizeof x)
#define MC(x,y) memcpy(x,y,sizeof x)
#define PLL pair<ll,ll>
#define lb(x) (x&-x)
using namespace std;
const int N=2500+5,M=1e5+5;
const ll INF=1ll<<60,mod=998244353;
int n,m,a[N];
db f[N][N];
int main(){
	IOS;cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+1+n,greater<int>());
	for(int i=1;i<=n;i++) f[i][i]=f[i-1][i-1]+1.0*a[i]/2;
	for(int i=1;i<=n;i++){
		for(int j=1;j<i;j++) f[i][j]=max((f[i-1][j-1]+a[i]+f[i-1][j])/2,f[i-1][j]);
	}
	cout<<fixed<<setprecision(6)<<f[n][n]*2.0-f[n][m]<<"\n";
	return 0;
}

posted @ 2025-11-30 16:21  tyh_27  阅读(1)  评论(0)    收藏  举报