zoukankan      html  css  js  c++  java
  • POJ2533&&1836&&3176

    终于写完了POJ的DP专题,然而都是水题233

    这次也把题目分了一下,先挑3道特别简单的讲一下

    2533

    题意:求最长上升子序列。

    很简单,用一般的DP或者二分优化都可以过去

    这里懒得写一般DP了,其实就是用f[i]表示前i个数中LIS的数量,那么在i之前找一个j,满足a[j]<a[j]并且f[j]最大,然后转移即可

    边界条件:f[i]=1

    二分的算法我也有所提及

    二分CODE

    #include<cstdio>
    using namespace std;
    const int N=1005;
    int f[N],top,n,x;
    inline char tc(void)
    {
    	static char fl[100000],*A=fl,*B=fl;
    	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0; char ch=tc();
    	while (ch<'0'||ch>'9') ch=tc();
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
    }
    inline int find(int x)
    {
    	int l=1,r=top,res=0;
    	while (l<=r)
    	{
    		int mid=l+r>>1;
    		if (f[mid]<x) res=mid,l=mid+1; else r=mid-1;
    	}
    	return res;
    }
    int main()
    {
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	register int i;
    	read(n);
    	for (i=1;i<=n;++i)
    	{
    		read(x);
    		if (!top) { f[++top]=x; continue; }
    		if (x<f[1]) f[1]=x;
    		int now=find(x); top=now+1>top?now+1:top;
    		f[now+1]=x;		
    	}
    	printf("%d",top);
    	return 0;
    }
    

    1836

    题意:类似于合唱队形好吧就是一样的

    给出n个人的身高,要求最少要多少人出列就可以使得所有的人都可以看见两边中的任意一边

    这里我们先处理出从前往后的LIS和从后往前的LIS,然后枚举一下哪两个人之间的人全部出队即可

    CODE

    #include<cstdio>
    using namespace std;
    const int N=1005;
    double a[N];
    int n,back[N],front[N],ans=0;
    inline int max(int a,int b)
    {
    	return a>b?a:b;
    }
    int main()
    {
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	register int i,j;
    	for (scanf("%d",&n),i=1;i<=n;++i)
    	scanf("%lf",&a[i]);
    	for (back[n]=1,i=n-1;i>=1;--i)
    	for (back[i]=1,j=i+1;j<=n;++j)
    	if (a[j]<a[i]) back[i]=max(back[i],back[j]+1);
    	for (front[1]=1,i=2;i<=n;++i)
    	for (front[i]=1,j=1;j<i;++j)
    	if (a[j]<a[i]) front[i]=max(front[i],front[j]+1);
    	for (i=0;i<=n;++i)
    	for (j=i+1;j<=n+1;++j)
    	ans=max(ans,front[i]+back[j]);
    	printf("%d",n-ans);
    	return 0;
    }
    

    3176

    题意:这道题都没有翻译题意,看看样例就知道是老掉牙的数字金字塔问题了

    DP即可,用f[i][j]表示到第i行第j列时最大值是多少,则

    f[i+1][j]=max(f[i+1][j],f[i][j]+a[i][j])
    f[i+1][j+1]=max(f[i+1][j+1],f[i][j]+a[i][j])
    

    CODE

    #include<cstdio>
    using namespace std;
    const int N=360;
    int f[N][N],x,n,ans;
    inline char tc(void)
    {
    	static char fl[100000],*A=fl,*B=fl;
    	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0; char ch=tc();
    	while (ch<'0'||ch>'9') ch=tc();
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
    }
    inline int max(int a,int b)
    {
    	return a>b?a:b;
    }
    int main()
    {
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	register int i,j;
    	for (read(n),i=1;i<=n;++i)
    	for (j=1;j<=i;++j)
    	read(x),f[i+1][j]=max(f[i+1][j],f[i][j]+x),f[i+1][j+1]=max(f[i+1][j+1],f[i][j]+x);
    	for (j=1;j<=n+1;++j)
    	ans=max(ans,f[n+1][j]);
    	printf("%d",ans);
    	return 0;
    }
    

    当然对于这种DP方程以我的尿性肯定是要滚存一下

    滚存CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=360;
    int f[2][N],x,n,ans;
    inline char tc(void)
    {
    	static char fl[100000],*A=fl,*B=fl;
    	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0; char ch=tc();
    	while (ch<'0'||ch>'9') ch=tc();
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
    }
    inline int max(int a,int b)
    {
    	return a>b?a:b;
    }
    int main()
    {
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	register int i,j;
    	for (read(n),i=1;i<=n;++i)
    	{
    		int now=i&1,nxt=now^1;
    		memset(f[nxt],0,sizeof(f[nxt]));	
    		for (j=1;j<=i;++j)
    		{
    			read(x); 
    			f[nxt][j]=max(f[nxt][j],f[now][j]+x),f[nxt][j+1]=max(f[nxt][j+1],f[now][j]+x);
    		}
    	}
    	for (j=1;j<=n+1;++j)
    	ans=max(ans,f[(n+1)&1][j]);
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    打破国外垄断,开发中国人自己的编程语言(2):使用监听器实现计算器
    寒假arcpy arcgis python培训通知
    分户图制作工具
    分户图制作工具
    Python3操作AutoCAD
    arcgis更新注记要素类
    arcgis field for cad
    为什么中小学培训这么火,怎么打击也收效甚微?
    arcgis arcmap使用 Python 加载 CAD 数据
    神仙渡劫
  • 原文地址:https://www.cnblogs.com/cjjsb/p/9028801.html
Copyright © 2011-2022 走看看