题意:求最长不递减子串
思路:直接扫一遍就好了~
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+6;
int ans = 0;
int a[maxn];
int res = 0;
int main()
{
int n;
scanf("%d",&n);
for (int i = 1;i<=n;i++)
scanf("%d",&a[i]);
for (int i = 2;i<=n;i++)
{
if (a[i]>=a[i-1]) {
res++;
ans = max(ans,res);
}
else res=0;
}
printf("%d\n",ans+1);
}
题意:
一个人有n个朋友,他想找他的n个朋友来玩,但是朋友间会相互攀比,就不能带他们的财富差距大于或等于d的,
他的朋友间还有好友度
求来的最大的朋友的友好度good
首先给你两个数n和d,分别代表有n个朋友,然后不超过d,
下面有n行,分别表示朋友的金钱数目和友好度(好有现实写照~)
思路:
先按照钱的多少排一下序,然后双指针暴力寻找最大的好友度
#include <bits/stdc++.h>
#define pr(x) cout << #x << "= " << x << " "
#define pl(x) cout << #x << "= " << x << endl;
#define Memset(x, a) memset(x, a, sizeof(x))
#define ll __int64
using namespace std;
const int inf=0x3f3f3f3f;
pair<ll,ll>a[100010];
ll n,d;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
bool cmp(pair<ll,ll> a,pair<ll,ll>b){
return a.first<b.first;
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
n=read();d=read();
for(int i=0; i<n; i++){
a[i].first=read();a[i].second=read();
}
sort(a,a+n,cmp);
ll st=0,ed=0,ans=0,sum=0;
while(ed<n){
while(a[ed].first-a[st].first<d&&ed<n){
sum+=a[ed].second;
ed++;
}
ans=max(ans,sum);
sum-=a[st].second;
st++;
}
cout<<ans<<endl;
return 0;
}
题意:
A的家在1,其余没有子节点的点都是餐厅,途中不能经过m次以上的红点(值为1)问他能去几个餐厅?
思路 : 深搜。需要注意的是他是无向的。
思路 : 深搜。需要注意的是他是无向的。
#include <bits/stdc++.h>
using namespace std;
int a[100010];
int vis[100010];
vector<int>v[100010];
int res=0;
int n,m;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int dfs(int cur,int res){ //层数 ,当前连续有猫数
if(a[cur])res++; //如果有猫,当前连续值+1
else res=0; //没猫,连续值置0
if(res>m||vis[cur])return 0; //如果连续有猫大于m或者该点被访问过返回0
vis[cur]=1;
int ans=0;
if(v[cur].size()==1&&cur>1)return 1; //如果访问到餐厅(没有子节点)
for(int i=0; i<v[cur].size(); i++){
ans+=dfs(v[cur][i],res);
}
return ans;
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
n=read();m=read();
for(int i=1; i<=n; i++){
a[i]=read();
}
for(int i=0; i<n-1; i++){
int x,y;
x=read();y=read();
v[x].push_back(y);
v[y].push_back(x);
}
cout<<dfs(1,0)<<endl;
return 0;
}
传送门: D. Kefa and Dishes
题意:
有n种菜,现在选m种菜来吃,还有很多条好处,如果在吃y的前一道菜是x的话,那么就可以获得满意度。每一种菜都有一个满意度。
思路:
裸的状态压缩dp,如果你敢写O(n^2*2^n)复杂度的代码的话,那基本就做完了。设dp[S][i]表示为最后一道菜为i,现在的菜吃的状态为S。S中的二进位如果为1表示已经吃了,如果是0则表示没吃,然后一个记忆化搜索,答案就出了了。
这道题基本就可以测出CF评测机的速度,n=18,O(n^2*2^n)复杂度的记忆化搜索代码跑了405ms,可见CF评测机1000ms跑10^9复杂度很轻松
#include <bits/stdc++.h>
#define Memset(x, a) memset(x, a, sizeof(x))
#define ll __int64
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,k;
ll v[20],buf[20][20];//v[]存每道菜满意度,buf[][]存不同顺序的增加满意度
ll dp[1<<19][20];
ll dfs(int S,int u,int p){ //已经访问过的节点集合S,当前位置u
if(dp[S][u]>=0)return dp[S][u]; //刚开始写的dp[][]>0结果test29超时,因为题目中ai都可以是0,所以细节啊啊啊~
if(p==m)return 0;
ll res=0;
for(int i=0; i<n; i++){
if(S&(1<<i))continue;
res=max(res,dfs(S^(1<<i),i,p+1)+v[i]+buf[u][i] );
}
return dp[S][u]=res;
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int x,y,val;
n=read();m=read();k=read();
for(int i=0; i<n; i++)
v[i]=read();
Memset(buf,0);
while(k--){
x=read();y=read();val=read();
buf[x-1][y-1]=val;
}
Memset(dp,-1);
printf("%I64d\n",dfs(0,19,0));
return 0;
}