11.14 解题报告

T1

考场用时:1 h
期望得分:70 pts
实际得分:20 pts
有一个地方的 m 写成了 n,直接 T 飞。
对于 70 分的做法,考虑设 dpi,j 表示分了 i 段,现在到 j 的最小代价,枚举 i 转移,复杂度 O(n2m)
发现其实段数是没必要枚举的,直接压掉一维,复杂度 O(nm),可以得 100 pts。

int dp[20001],st[20001][21][2],lg[MAX];
inline int w(int l,int r){
	int len=lg[r-l+1];
	int mn=min(st[l][len][0],st[r-(1ll<<len)+1][len][0]);
	int mx=max(st[l][len][1],st[r-(1ll<<len)+1][len][1]);
	return mx-mn;
}
signed main(){
	int n=read(),m=read(),K=read();
	for(int i=1;i<=n;i++) dp[i]=1e18;
	for(int i=1;i<=n;i++) st[i][0][0]=st[i][0][1]=read();
	lg[0]=-1;
	for(int i=1;i<=n;i++) lg[i]=lg[i>>1]+1;
	for(int i=1;i<=20;i++)
		for(int j=1;j+(1ll<<i)-1<=n;j++){
			st[j][i][0]=min(st[j][i-1][0],st[j+(1ll<<(i-1))][i-1][0]);
			st[j][i][1]=max(st[j][i-1][1],st[j+(1ll<<(i-1))][i-1][1]);
		}
	dp[0]=0;
		for(int j=1;j<=n;j++){
			for(int k=max(0ll,j-m);k<j;k++)
				dp[j]=min(dp[j],dp[k]+w(k+1,j)*(j-k)+K);
		}
	cout<<dp[n];
	return 0;
}

T2

考场用时:30 min
期望得分:30 pts
实际得分:0 pts
爆搜写假了,考虑贪心,对于若干个连续的 1,如果只有 1 个,显然直接加上是最优的,对于答案的贡献是 1,如果有 21,假设有 x1,此时可以花费 1 的代价构造出 1 后面跟着 x0,然后再减 1,此时代价是 2,优于一个一个加。

具体实现可以从头到尾扫一遍字符串,记录当前连续 1 的个数,考虑反过来,按照以上原则,把 1 全部消掉。

char s[MAX];
signed main(){
	int n=read();
	scanf("%s",s+1);
	int js=0,ans=0;
	for(int i=1;i<=n;i++){
		if(s[i]=='1') js++;
		else{
			if(js==1) ans++,js=0;
			else if(js>1) ans++,js=1;
		}
	}
	ans+=min(js,2ll);
	cout<<ans;
	return 0;
}
posted @   wapmhac  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示