A:找出最长连续不递减子序列....直接遍历寻找即可...
#include<bits/stdc++.h>
using namespace std;
int a[110000];
int main()
{
int n;
scanf("%d",&n);
a[0]=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int ans=0,tmp=0;
for(int i=1;i<=n;i++)
{
if(a[i]>=a[i-1])
tmp++;
else
{
ans=max(ans,tmp);
tmp=1;
}
}
ans=max(ans,tmp);
cout<<ans<<endl;
return 0;
}
B.给定n个人,每个人有m(工资)和s(不知道是啥)两个属性,要求找到一个人的集合,这个集合内工资最多的人比工资最低的人的差值小于d,问所有可能集合内所有人的s属性和的最大值。
排序+尺取法
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct node
{
int m,s;
}s[110000];
int cmp(node a,node b)
{
return a.m<b.m;
}
int main()
{
int n,d;
cin>>n>>d;
for(int i=1;i<=n;i++)
scanf("%d %d",&s[i].m,&s[i].s);
ll ans=0,ti=1,tj=1,tmp=0;
sort(s+1,s+n+1,cmp);
while(tj<=n)
{
while(s[tj].m-s[ti].m<d&&tj<=n)
{
tmp+=s[tj].s;
tj++;
}
ans=max(ans,tmp);
tmp-=s[ti].s;
ti++;
}
ans=max(ans,tmp);
cout<<ans<<endl;
return 0;
}
C.给定一个点n,然后每个点的权值,只有0和1,1代表有猫,主角因为怕猫所以不能连续经过超过m个有猫的点,问主角能到达多少个叶子节点.根结点是1.
题目并没有说给的边是有向的,所以直接无向图建边,然后度数为1的除了可能是根以外就是叶子了..
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 110000
int head[N],t;
struct edge
{
int u,v,next;
}edge[N*2];
int n,m,in[N],a[N],used[N];
void add(int u,int v)
{
edge[t].v=v;
edge[t].next=head[u];
head[u]=t++;
}
int dfs(int u,int s)
{
used[u]=1;
if(a[u]==1) s++;
else s=0;
if(s>m) return 0;
if(in[u]==1&&u!=1)
return 1;
int ans=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(used[v]==0)
ans+=dfs(v,s);
}
return ans;
}
int main()
{
memset(in,0,sizeof(in));
memset(head,-1,sizeof(head));
memset(used,0,sizeof(used));
t=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int u,v;
for(int i=0;i<n-1;i++)
{
scanf("%d %d",&u,&v);
add(u,v);
add(v,u);
in[u]++;
in[v]++;
}
int ans=dfs(1,0);
cout<<ans<<endl;
return 0;
}
D,给定n个菜,每个菜都有一个美味值,然后支持m个菜,如果按照给定的k个规则吃会有额外的美味值加成,对于一个规则来说,u,v,w代表先吃u再吃v可以额外获得w,u v之间不能吃其他菜。
状压dp,dp[i][j]代表i这个状态下,最后一次吃的是j所能获得的最大美味值...
很久不写状压dp根本不会写了,手残写错了一个括号,成功没过题..赛后被人看出来,真是无语到爆,状压要注意运算级的问题。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 110000
ll dp[300000][20];
int a[20];
int mp[20][20];
int pd(int i)
{
int ans=0;
while(i)
{
ans+=i%2;
i=i/2;
}
return ans;
}
int main()
{
int n,m,k,u,v,w;
scanf("%d %d %d",&n,&m,&k);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
memset(mp,0,sizeof(mp));
for(int i=1;i<=k;i++)
{
scanf("%d %d %d",&u,&v,&w);
u--;v--;
mp[u][v]=w;
}
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
dp[1<<i][i]=a[i];
ll ans=0;
for(int i=1;i<(1<<n);i++)
{
if(pd(i)>m) continue;
for(int j=0;(1<<j)<=i;j++)
{
if((i&(1<<j))==0)
continue;
int t=i-(1<<j);
for(int k=0;(1<<k)<=t;k++)
{
if((t&(1<<k))==0) continue;
dp[i][j]=max(dp[t][k]+a[j]+mp[k][j],dp[i][j]);
}
}
}
for(int i=1;i<(1<<n);i++)
{
if(pd(i)!=m) continue;
for(int j=0;(1<<j)<=i;j++)
ans=max(dp[i][j],ans);
}
cout<<ans<<endl;
return 0;
}