NEUQ-ACM预备队必做题4.0

B3637 最长上升子序列

不断保存当前最长的长度。

#include<bits/stdc++.h>
using namespace std;
int dp[5001];
int main()
{
	int n,mmax=0;
	cin>>n;
	int a[n+1];
	for(int i=1;i<=n;++i)
	  cin>>a[i];
	for(int i=1;i<=n;++i)
	  {
	  	dp[i]=1;
	  	for(int j=1;j<i;++j)
	  	  if(a[i]>a[j])
	  	    dp[i]=max(dp[i],dp[j]+1);
		}  
	for(int i=1;i<=n;++i)
	  mmax=max(mmax,dp[i]);
	  
	cout<<mmax;  	
	return 0;
} 

P1115 最大子段和

贪心吧,如果当前比前面一堆相加还大,更新左边界,始终记录max。

#include<bits/stdc++.h>
using namespace std;
int n;
int mmax=-100000;
int main()
{
	cin>>n;
	int a,b;
	cin>>a;
	b=a;
	for(int i=2;i<=n;++i)
	{
	  cin>>a;
      b=max(a,a+b); 
      mmax=max(b,mmax);  
	}	
	cout<<mmax;  
} 

P8707 [蓝桥杯 2020 省 AB1] 走方格

dp不断更新每个点的可行路径数

#include<bits/stdc++.h>//dfs
using namespace std;
int n,m,ans=0;
int a[10001][10001];

int main()
{
	a[1][1]=1;
	cin>>n>>m;
    for(int i=1;i<=n;++i)
      for(int j=1;j<=m;++j)
        if(i&1||j&1) 
          a[i][j]+=a[i-1][j]+a[i][j-1];
	cout<<a[n][m];
} 

P1216 [USACO1.5] [IOI1994]数字三角形 Number Triangles

倒着走,更新当前状态的最大值。

#include<bits/stdc++.h>//dfs
using namespace std;
int n,m,ans=0;
int a[10001][10001];
int main()
{
	cin>>n;
    for(int i=1;i<=n;++i)
      for(int j=1;j<=i;++j)
        cin>>a[i][j];
    for(int i=n-1;i>=1;--i)
	  for(int j=1;j<=i;++j)
	    a[i][j]+=max(a[i+1][j],a[i+1][j+1]);    
	cout<<a[1][1];
} 

P1020 [NOIP1999 普及组] 导弹拦截

1.对于问题1求最长不上升序列通过将每个数以二分的方式进入dp中,确保当前状态下每个数尽可能大。

2.对于问题二Dilworth定理,不会证明,但是可以通过把哈斯图画出来直观的感受。

ps注意输入的方式,防止卡常数,像我一样QAQ

#include<bits/stdc++.h>
#define f(i,x,y) for(int i=(x);i<=(y);++i) 
using namespace std;
int n=0,ans1=1,ans2=1;
int s[100001],a[100001];
void input() {
    do {
        n++;
    } while (cin >> a[n]);
    n--;
}
void chushihua()
{
	memset(s,0,sizeof(s));
	return;
}
int get_ans1()
{
	chushihua();
	s[ans1]=a[1];
	for(int i=2;i<=n;++i)
	  {
	  	if(a[i]<=s[ans1])
	  	  {
	  	  	s[++ans1]=a[i];
	  	 // 	cout<<" "<<a[i];
	  	  	continue;
	      }
	    int l=1,r=ans1,mid;
		while(l<r)
		  {
		  	mid=(l+r)>>1;
		  	if(a[i]>s[mid])
		  	  r=mid;
		  	else
			  l=mid+1;  
		  }
		  s[r]=a[i];
	  } 
	  return ans1;
}
int get_ans2()
{
	chushihua();
	s[ans2]=a[1];
	for(int i=2;i<=n;++i)
	  {
	  	if(a[i]>s[ans2])
	  	  {
	  	  	s[++ans2]=a[i];
	  	  	continue;
	      }
	    int l=1,r=ans2,mid;
		while(l<r)
		  {
		  	mid=(l+r)>>1;
		  	if(a[i]<=s[mid])
		  	  r=mid;
		  	else
			  l=mid+1;  
		  }
		  s[r]=a[i];
	  } 
	  return ans2;
}
int main()
{
	input();
	cout<<get_ans1()<<endl<<get_ans2();  	
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值