训练日记

https://cn.vjudge.net/contest/232326#problem/I

从左到右拿盘子,放置盘子的方式是从小到大,所以是最长上升子序列和最长下降子序列。。。。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x7ffffff
int a[505];
int b[505],c[505];
int main()
{
    int i,j,n,k,ans,maxn;
    while(~scanf("%d",&n)&&n)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        ans=0;
        for(i=n;i>0;i--)
        {
            maxn=1;
            for(j=n;j>i;j--)
            {
                if(a[j]>=a[i])
                {
                    maxn=max(maxn,b[j]+1);
                }
            }
            b[i]=maxn;
            maxn=1;
            for(j=n;j>i;j--)
            {
                if(a[j]<=a[i])
                {
                    maxn=max(maxn,c[j]+1);
                }
            }
            c[i]=maxn;
        }
        for(i=1;i<=n;i++)
        {
            ans=max(ans,max(b[i],c[i]));
            for(j=i+1;j<=n;j++)
            {
                if(a[i]>a[j])
                    ans=max(ans,b[i]+c[j]);
                else
                if(a[i]<a[j])
                ans=max(ans,b[j]+c[i]);
            }
        }
        printf("%d\n",ans);
    }
}

https://cn.vjudge.net/contest/232326#problem/S

题意:

最长公共子序列可以转化为最长上升子序列

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x7ffffff
int a[100005],b[100005],dp[100005];
int main()
{
    int t,i,j,p,q,n,x,k,len;
    k=0;
    scanf("%d",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));
        scanf("%d%d%d",&n,&p,&q);
        for(i=0;i<=p;i++)
        {
            scanf("%d",&x);
            a[x]=i;
        }
        len=1;
        scanf("%d",&x);
        dp[1]=a[x];
        for(i=1;i<=q;i++)
        {
            scanf("%d",&x);
            if(a[x]>dp[len])
            {
                dp[++len]=a[x];
            }
            else
            {
                int u;
                u=lower_bound(dp+1,dp+len+1,a[x])-dp;
                dp[u]=a[x];
            }
        }
        k++;
        printf("Case %d: %d\n",k,len);
    }
}

https://cn.vjudge.net/contest/232326#problem/P

就是贪心查找最小的n组差,贪心是先排序,然后用一个dp就行了

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x7ffffff
double dp[505][505],a[505],b[505];
int main()
{
    int n,i,j,m,k,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
            scanf("%lf",&a[i]);
        for(i=1;i<=m;i++)
            scanf("%lf",&b[i]);
        sort(a+1,a+n+1);
        sort(b+1,b+1+m);
        if(n<m)
        {
            dp[0][0]=0;
            for(j=0;j<=m;j++)
                dp[0][j]=0;
            for(i=1;i<=n;i++)
                for(j=0;j<=m;j++)
                dp[i][j]=inf;
            for(i=1;i<=n;i++)
            {
                int tt;
                tt=m-(n-i);
                for(j=i;j<=tt;j++)
                {
                    dp[i][j]=min(dp[i][j-1],dp[i-1][j-1]+abs(a[i]-b[j]));
                }
            }
            printf("%.1f\n",dp[n][m]);
        }
        else
        {
            dp[0][0]=0;
            for(j=0;j<=n;j++)
                dp[0][j]=0;
            for(i=1;i<=m;i++)
                for(j=0;j<=n;j++)
                dp[i][j]=inf;
            for(i=1;i<=m;i++)
            {
                int tt;
                tt=n-(m-i);
                for(j=i;j<=tt;j++)
                {
                    dp[i][j]=min(dp[i][j-1],dp[i-1][j-1]+abs(b[i]-a[j]));
                }
            }
            printf("%.1f\n",dp[m][n]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lml11111/article/details/80560557