2025/1/4课堂记录
目录
- 修剪草坪
- 周年纪念晚会
-
修剪草坪
朴素的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;
}
本文来自博客园,作者:永韶,转载请注明原文链接:https://www.cnblogs.com/yongshao/p/18652565