2025/1/4课堂记录

目录

  1. 修剪草坪
  2. 周年纪念晚会

  • 修剪草坪

    朴素的dp版
    查看代码
    #include<iostream>
    using namespace std;
    long long int a[100010];
    long long int yes[100010],no[100010];//第i个数要/不要,1-i之间,最大效率;
    long long int max(long long int a,long long int b)
    {
    	if(a>b)return a;
    	else return b;
    }
    int main()
    {
    	int n,k;
    	cin>>n>>k;
    	for(int i=1;i<=n;i++)
    	{
    		int x;
    		cin>>x;
    		a[i]=a[i-1]+x;
    	}
    	for(int i=1;i<=n;i++)
    	{
    		no[i]=max(yes[i-1],no[i-1]);
    		for(int j=max(0,i-k);j<i;j++)
    			yes[i]=max(yes[i],no[j]+a[i]-a[j]); //j不要,j+1---i要 
    	}
    	cout<<max(no[n],yes[n]);
    	return 0;
    }

    单调队列版

查看代码
 #include<iostream>
using namespace std;
long long int a[100010];
long long int yes[100010],no[100010];//第i个数要/不要,1-i之间,最大效率;
long long int max(long long int a,long long int b)
{
	if(a>b)return a;
	else return b;
}
int q[100010];
int main()
{
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		a[i]=a[i-1]+x;
	}
	int l=0,r=1; 
	q[0]=0;
	for(int i=1;i<=n;i++)
	{
		while(l<r&&q[l]<i-k)l++;
		no[i]=max(yes[i-1],no[i-1]);
		yes[i]=a[i]-a[q[l]]+no[q[l]];
		while(l<r&&a[q[r-1]]>a[i])r--;
		q[r++]=i;
//		for(int j=max(0,i-k);j<i;j++)
//			yes[i]=max(yes[i],no[j]+a[i]-a[j]); //j不要,j+1---i要 
	}
	cout<<max(no[n],yes[n]);
	return 0;
}

有bug(20分)

50分
 #include<iostream>
using namespace std;
long long int a[100010];
long long int yes[100010],no[100010];//第i个数要/不要,1-i之间,最大效率;
long long int max(long long int a,long long int b)
{
	if(a>b)return a;
	else return b;
}
int q[100010];
int main()
{
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		a[i]=a[i-1]+x;
	}
	int l=0,r=1; 
	q[0]=0;
	for(int i=1;i<=n;i++)
	{
		while(l<r&&q[l]<i-k)l++;
		no[i]=max(yes[i-1],no[i-1]);
		yes[i]=a[i]-a[q[l]]+no[q[l]];
		while(l<r&&no[q[r-1]]-a[q[r-1]]<no[i]-a[i])r--;
		q[r++]=i;
//		for(int j=max(0,i-k);j<i;j++)
//			yes[i]=max(yes[i],no[j]+a[i]-a[j]); //j不要,j+1---i要 
	}
	cout<<max(no[n],yes[n]);
	return 0;
}

 


这是一道树形dp题

90分
 #include<iostream>
using namespace std;
const int maxn=6000;
struct edge
{
	int next;
	int to;
}edge[2*maxn+10];
int head[maxn],tot,n;
// 邻接表 存储 树边 
void add_edge(int from,int to)
{
	++tot;
	edge[tot].next=head[from];
	edge[tot].to=to;
	head[from]=tot;
}
int f[maxn+10][2];

//  f[i][0]:以i作为子树树根的时候,i结点不选的整颗子树的最大价值;
//  f[i][1]:以i作为子树树根的时候,i结点选的整颗子树的最大价值;

int value[maxn+10];
int dfs(int p,int fa)
{
	for(int i=head[p];i;i=edge[i].next)  //for(int i=0;i<vec[p].size();i++) 
	{
		int to=edge[i].to;               //    int to=vec[p][i]; 
		if(to==fa)
		    continue;
		//先把孩子计算完,再计算父亲 
		dfs(to,p);
		//f[p][0] :父亲结点不去;那么孩子可取可不去; 
		f[p][0]+=max(f[to][0],f[to][1]);
		//f[p][1] :父亲结点去,那么孩子肯定不能去; 
		f[p][1]+=f[to][0];
	}
}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>value[i];
		f[i][1]=value[i];
		f[i][0]=0;
	}
	// 一棵树 n个顶点,n-1条边 
	for(int i=1;i<n;i++)
	{
		int L,K;
		cin>>L>>K;
		add_edge(K,L);  //vec[K].push_back(L); 
		add_edge(L,K);  //vec[L].push_back(K); 
	}
	dfs(1,-1);  //root  1 
	cout<<max(f[1][0],f[1][1])<<endl;
	return 0;
}

 

posted @ 2025-01-04 22:09  永韶  阅读(14)  评论(0编辑  收藏  举报