随笔 - 531  文章 - 0  评论 - 3  阅读 - 10215 

有n个高度都为h的树(b[i]) ,树上的一些高度处有若干果实(比如b[i][h]==3) ,猫从任意的树顶部出发,可以

1.跳到任意其他的树上,高度将下降D

2.向下滑1个单位

问最多获得多少果实?

明显的dp

暴力程序 O(n^3) 

#include <iostream>
#include <algorithm>
using namespace std ;
 const int M=2003,N=5003;
 
 int n,h,D,f[N][M];
 int b[N][M];
 
 void solve(){
 	int i,j,k,ans=0;
 	
 	for(j=0;j<=h;j++)
 	for(i=1;i<=n;i++){
 	 	f[i][j]=max(f[i][j],f[i][j-1]+b[i][j]); 
 	 	for(k=1;k<=n;k++){
		  if(k!=i&&j>=D) f[i][j]=max(f[i][j],f[k][j-D]+b[i][j]);
	    }
	  }
	
	for(i=1;i<=n;i++) ans=max(ans,f[i][h]);
	cout<<ans;
 }
 signed main(){
 	int i,x,t;
 	cin>>n>>h>>D;
 	for(i=1;i<=n;i++){
 		cin>>t;
 		while(t--) cin>>x,b[i][x]++;
	 }
 	solve();
 }

 
 

重点来了,可以去掉 k 的枚举

 f[i][j]=max(f[i][j],f[k][j-D]+b[i][j]);

k的枚举的目的是 找 f[k][height]  最大,可以维护一下,然后直接用

 ht[j] 表示高度j 时 , f[k][j] 的最大值

er高度是也从小到大枚举的,没毛病

O(n^2)

#include <iostream>
#include <algorithm>
using namespace std ;
 const int M=2003,N=5003;
 
 int n,h,D,f[N][M],ht[M];
 int b[N][M];
 
 void solve(){
 	int i,j,k,ans=0;
 	
 	for(j=0;j<=h;j++)
 	for(i=1;i<=n;i++){
 	 	f[i][j]=max(f[i][j],f[i][j-1]+b[i][j]); 
		 // if(k!=i&&j>=D) f[i][j]=max(f[i][j],f[k][j-D]+b[i][j]);
	    
	    if(j>=D) f[i][j]=max(f[i][j],ht[j-D]+b[i][j]);
	    ht[j]=max(ht[j],f[i][j]);
	  }
	
	for(i=1;i<=n;i++) ans=max(ans,f[i][h]);
	cout<<ans;
 }
 signed main(){
 	int i,x,t;
 	cin>>n>>h>>D;
 	for(i=1;i<=n;i++){
 		cin>>t;
 		while(t--) cin>>x,b[i][x]++;
	 }
 	solve();
 }

 
 

posted on   towboat  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示