基础dp专题结题报告

HDU - 1024

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

LL a[1000005];
LL mx[1000005];
LL dp[1000005];
int main()
{
    int m,n;
    while(~scanf("%d%d",&m,&n))
    {
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        memset(dp,0,sizeof(dp));
        memset(mx,0,sizeof(mx));
        LL tmp=-inf;
        for(int i=1;i<=m;i++)
        {
            tmp=-919999999999999999LL;
            for(int j=i;j<=n;j++)
            {
                if(i==j)dp[j]=dp[j-1]+a[j];
                else
                dp[j]=max(dp[j-1],mx[j-1])+a[j];
                mx[j-1]=tmp;
                if(dp[j]>tmp)tmp=dp[j];
            }
        }
        cout<<tmp<<endl;
    }
}
/*
n个数中取出m段,要求m段的和最大。
每新加入一个数,要么自己独立成一段,要么跟前边那一个数
属于同一段。
所以dp[i][j]表示j个数分i段必须取j的最大值。
对于dp[i][j]=max(dp[i][j-1],max(dp[i-1][k])+a[j]) (k->[1,j-1]);
dp[i][j]的值依赖于dp[i][j-1]和dp[i-1][k];
可以用滚动数组。
其实dp[i-1][k]就是上一行1-(j-1)的最大值,我们可以用一个一维数组记录。
既mx数组。
这样dp数组也可以用一维的了。
*/

HDU - 1029 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int sum=0;
        int ans;
        for(int i=1;i<=n;i++)
        {
            int tmp;
            sca(tmp);
            if(sum==0)
            {
                ans=tmp;
                sum++;
            }
            else if(tmp==ans)
            {
                sum++;
            }
            else sum--;
        }
        printf("%d\n",ans);
    }
}
/*
求出现次数为(n+1)/2次的数,n为奇数
1.排序,中中位数。
2.考虑不同数抵消。最后剩下的是要求的数。
*/

HDU - 1069

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

struct node
{
    int x,y,z;
    friend bool operator <(node a,node b)
    {
        if(a.x!=b.x)return a.x<b.x;
        else return a.y<b.y;
    }
}a[100005];
int dp[10005];
int main()
{
    int n;
    int cas=1;
    while(cin>>n&&n)
    {
        int cnt=1;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[cnt].x=x,a[cnt].y=y,a[cnt].z=z,cnt++;
            a[cnt].x=x,a[cnt].y=z,a[cnt].z=y,cnt++;
            a[cnt].x=y,a[cnt].y=x,a[cnt].z=z,cnt++;
            a[cnt].x=y,a[cnt].y=z,a[cnt].z=x,cnt++;
            a[cnt].x=z,a[cnt].y=x,a[cnt].z=y,cnt++;
            a[cnt].x=z,a[cnt].y=y,a[cnt].z=x,cnt++;
        }

        sort(a+1,a+cnt);
        int ans=-199;
        for(int i=1;i<cnt;i++)dp[i]=a[i].z;
        for(int i=1;i<cnt;i++)
        {
            for(int j=1;j<i;j++)
            {
                if(a[j].x<a[i].x&&a[j].y<a[i].y)
                {
                    dp[i]=max(dp[i],dp[j]+a[i].z);
                    ans=max(ans,dp[i]);
                }
            }
        }
        printf("Case %d: maximum height = ",cas++);
        cout<<ans<<endl;
    }
}
/*
给了一维2微的x和y,一个高度
要求x和y都是严格递减的,求最大高度。其中每种方块都有无限个。
每个方块通过旋转最多产生6种方块。
对一维排序,对另一维求一个最长下降子序列。
如果要求每种块的最大高度就是cdq分治了。
*/

HDU - 1074 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

string str[20];
int dead[20],cost[20];
int dp[1<<16];
int T[1<<16];
int pre[1<<16],name[1<<16];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        sca(n);
        memset(dp,inf,sizeof(dp));
        memset(T,0,sizeof(T));
        for(int i=0;i<n;i++)
        {
            cin>>str[i]>>dead[i]>>cost[i];
        }
        int bit=1<<n;
        T[0]=0;
        dp[0]=0;
        for(int i=1;i<bit;i++)
        {
            for(int j=n;j>=0;j--)
            {
                int tmp=1<<j;
                if(!(i&tmp))continue;
                int tmp1=i^tmp;
                int red=max(T[tmp1]+cost[j]-dead[j],0);
                int v=dp[tmp1]+red;
                //cout<<i<<" "<<j<<" "<<v<<endl;
                if(v<dp[i])
                {
                    dp[i]=v;
                    pre[i]=tmp1;
                    T[i]=T[tmp1]+cost[j];
                    name[i]=j;
                }
            }
        }
        stack<int>s;
        int now=bit-1;
        while(now!=0)
        {
            s.push(name[now]);
            now=pre[now];
        }
        cout<<dp[bit-1]<<endl;
        while(!s.empty())
        {
            cout<<str[s.top()]<<endl;
            s.pop();
        }
    }
}
/*
001 010 011 100 101 110 111
没想到是状态亚索dp
想到了一个比较麻烦的dp
就是依次确定长度为1-n的序列的顺序,然后长度每增加1,我就枚举当前点在
之前序列中的位置。可以确定这样枚举到最后一定能取得最优值。
但是实现起来比较麻烦。因为我们需要不断变换位置,并且统计当前的花费。
仔细想一想,我们其实不用变换位置,因为位置是相对的。
这个状态亚索dp正是利用了这一点吧。

例如n=3 我们有上边8种状态。
当我们枚举i时如果j的位置为1,我们就由之前的状态(j的位置为0)推出当前
i的状态。(这不就相当于把j从原来顺序中拿出来放到最后嘛)。
例如当dp[011]的值确定的时候,我们就相当于确定了当序列的长度为2的时候的
取最优值的一个顺序。
又例如
dp[011] [101] dp[110] 就枚举了长度为2的所有可能的排列。
2 3
3 2
1 3
3 1
1 2
2 1
这就很好解决了上边有思路却无法实现的问题。
*/

HDU - 1087

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

LL a[1005];
LL dp[1005];
int main()
{
    int n;
    while(cin>>n&&n)
    {
        for(int i=1;i<=n;i++)scanf("%lld",a+i);
        a[0]=-999999999999LL;
        a[n+1]=999999999999LL;
        memset(dp,0,sizeof(dp));
        LL ans=-999999999999;
        for(int i=1;i<=n+1;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(a[j]<a[i])
                {
                    dp[i]=max(dp[i],dp[j]+a[i]);
                    ans=max(ans,dp[i]);
                }
            }
        }
        cout<<ans-999999999999<<endl;
    }
}
/*

*/

HDU - 1114

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

int dp[100005][12];
int sum[100005][12];
int pos[100005][12];
int M(int x,int y,int z)
{
    return max(max(x,y),z);
}

int main()
{
    int n;
    while(cin>>n&&n)
    {
        int maxt=0;
        memset(dp,0,sizeof(dp));
        memset(sum,0,sizeof(sum));
        for(int i=1; i<=n; i++)
        {
            int x,t;
            scanf("%d%d",&x,&t);
            sum[t][x]++;
            maxt=max(maxt,t);
        }
        int ans=0;
        pos[0][5]=1;
        for(int i=1; i<=maxt; i++)
        {
            for(int j=0;j<=10;j++)
            {
                if(pos[i-1][j]==1)pos[i][j]=pos[i][j-1]=pos[i][j+1]=1;
            }
            for(int k=0; k<=10; k++)
            {
                if(pos[i][k]==0)continue;
                if(k==0)dp[i][k]=max(dp[i-1][k],dp[i-1][k+1])+sum[i][k];
                else if(k==10)dp[i][k]=max(dp[i-1][k],dp[i-1][k-1])+sum[i][k];
                else dp[i][k]=M(dp[i-1][k-1],dp[i-1][k],dp[i-1][k+1])+sum[i][k];
                ans=max(ans,dp[i][k]);
            }
        }
        cout<<ans<<endl;
    }
}
/*
对于每一个时刻,处理处下一时刻能到达的位置。
然后对能到达的位置进行状态转移。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

struct node
{
    int p,w;
}a[505];

int dp[3][10005];
int main()
{
    int t;
    sca(t);
    while(t--)
    {
        int e,f;
        scanf("%d%d",&e,&f);
        int n;
        sca(n);
        for(int i=1;i<=n;i++)
        {
            sca(a[i].p),sca(a[i].w);
        }

        memset(dp,inf,sizeof(dp));

        int W=f-e;
        dp[0][0]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=W;j++)
            {
                if(j<a[i].w)dp[(i)%2][j]=dp[(i-1)%2][j];
                else dp[i%2][j]=min(dp[(i-1)%2][j],dp[i%2][j-a[i].w]+a[i].p);
                //cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
            }
        }
        if(dp[n%2][W]==inf)puts("This is impossible.");
        else printf("The minimum amount of money in the piggy-bank is %d.\n",dp[n%2][W]);
    }
}

HDU - 1176

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

int dp[100005][12];
int sum[100005][12];
int pos[100005][12];
int M(int x,int y,int z)
{
    return max(max(x,y),z);
}

int main()
{
    int n;
    while(cin>>n&&n)
    {
        int maxt=0;
        memset(dp,0,sizeof(dp));
        memset(sum,0,sizeof(sum));
        for(int i=1; i<=n; i++)
        {
            int x,t;
            scanf("%d%d",&x,&t);
            sum[t][x]++;
            maxt=max(maxt,t);
        }
        int ans=0;
        pos[0][5]=1;
        for(int i=1; i<=maxt; i++)
        {
            for(int j=0;j<=10;j++)
            {
                if(pos[i-1][j]==1)pos[i][j]=pos[i][j-1]=pos[i][j+1]=1;
            }
            for(int k=0; k<=10; k++)
            {
                if(pos[i][k]==0)continue;
                if(k==0)dp[i][k]=max(dp[i-1][k],dp[i-1][k+1])+sum[i][k];
                else if(k==10)dp[i][k]=max(dp[i-1][k],dp[i-1][k-1])+sum[i][k];
                else dp[i][k]=M(dp[i-1][k-1],dp[i-1][k],dp[i-1][k+1])+sum[i][k];
                ans=max(ans,dp[i][k]);
            }
        }
        cout<<ans<<endl;
    }
}
/*
对于每一个时刻,处理处下一时刻能到达的位置。
然后对能到达的位置进行状态转移。
*/

HDU - 1260 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

int a[2005];
int b[2005];
int dp[2005][2];
int main()
{
    int t;
    sca(t);
    while(t--)
    {
        int n;
        sca(n);
        for(int i=1;i<=n;i++)sca(a[i]);
        for(int i=1;i<n;i++)sca(b[i]);
        memset(dp,inf,sizeof(dp));
        dp[1][0]=dp[1][1]=a[1];
        dp[2][1]=a[1]+a[2];
        dp[2][0]=b[1];
        for(int i=3;i<=n;i++)
        {
            dp[i][0]=min(dp[i-1][1],min(dp[i-2][0],dp[i-2][1]))+b[i-1];
            dp[i][1]=min(dp[i-1][1],dp[i-1][0])+a[i];
        }
        int en=min(dp[n][0],dp[n][1]);
        int h=(8+en/3600)%24;
        en%=3600;
        int f=en/60;
        en%=60;
        int flag=0,tmp=0;
        if(h>=12)
        {
            flag=1;
        }
        printf("%02d:%02d:%02d ",h,f,en);
        if(flag)puts("pm");
        else puts("am");
    }
}

HDU - 1257

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

int a[10005],b[10005];
int cnt;
int erfen(int val)
{
    int l=1,r=cnt;
    while(l<=r)
    {
        int m=(l+r)>>1;
        if(val<=b[m])r=m-1;
        else l=m+1;
    }
    //cout<<l<<" "<<r<<endl;
    return r+1;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)sca(a[i]);
        b[1]=a[1];
        cnt=1;
        for(int i=2;i<=n;i++)
        {
            int pos=erfen(a[i]);
            b[pos]=a[i];
            //cout<<pos<<endl;
            if(pos>cnt)cnt++;
        }
        cout<<cnt<<endl;
    }
}
/*
1 4 2
*/

HDU - 1160 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

struct node
{
    int a,b,id;
    friend bool operator <(node x,node y)
    {
        return x.a<y.a;
    }
}c[1005],d[1005];

int dp[1005];
int path[1005];

void Pri(int p)
{
    if(p==0)return ;
    Pri(path[p]);
    cout<<d[p].id<<endl;
}
int main()
{
    int cnt=1;
    while(cin>>c[cnt].a>>c[cnt].b)
    {
        c[cnt].id=cnt;
        cnt++;
    }
    sort(c+1,c+cnt);
    int now=1;
    for(int i=1;i+1<=cnt;i++)
    {
        d[now]=c[i];
        //cout<<c[i].a<<" "<<c[i].b<<endl;
        if(c[i].a==c[i+1].a&&c[i].b==c[i+1].b)continue;
        now++;
    }
    int ans=0;
    for(int i=1;i<now;i++)
    {
        for(int j=1;j<i;j++)
        {
            if(d[i].b<d[j].b&&d[i].a!=d[j].a)
            {
                if(dp[i]<dp[j]+1)
                {
                    dp[i]=dp[j]+1;
                    path[i]=j;
                    ans=max(ans,dp[i]);
                }
            }
        }
    }
    int pos;
    for(int i=now-1;i>=0;i--)
    {
        if(dp[i]==ans)
        {
            pos=i;
            break;
        }
    }
    cout<<ans+1<<endl;
    Pri(pos);
}

POJ - 1015

这个应该是最难得一个了,转化为背包问题求解,n代表物品,m代表背包容量。

枚举绝差值,进行状态转移。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<vector>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
#define N 205
int dp[2][22][805];
int c[N],d[N];
int a[N],b[N];
vector<int>path[2][22][805];

void init()
{
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<22;j++)
        {
            for(int k=0;k<804;k++)path[i][j][k].clear();
        }
    }
}
int main()
{
    int n,m;
    int cas=1;
    while(cin>>n>>m&&(n+m))
    {
        init();
        for(int i=1;i<=n;i++)
        {
            sca(a[i]),sca(b[i]);
            c[i]=a[i]+b[i];
            d[i]=a[i]-b[i];
        }
        memset(dp,-1,sizeof(dp));
        int fix=20*m;
        dp[0][0][fix]=0;
        for(int i=1;i<=n;i++)
        {
            dp[i%2][0][fix]=0;
            for(int j=1;j<=m;j++)
            {
                for(int k=d[i];k<=20*m+fix;k++)
                {
                    if(dp[(i-1)%2][j][k]!=-1)dp[i%2][j][k]=dp[(i-1)%2][j][k],path[i%2][j][k]=path[(i-1)%2][j][k];
                    if(dp[(i-1)%2][j-1][k-d[i]]==-1)continue;
                    if(k<0||k-d[i]>20*m+fix)continue;
                    if(dp[(i-1)%2][j-1][k-d[i]]+c[i]>dp[i%2][j][k])
                    {
                        dp[i%2][j][k]=dp[(i-1)%2][j-1][k-d[i]]+c[i];
                        path[i%2][j][k]=path[(i-1)%2][j-1][k-d[i]];
                        path[i%2][j][k].pb(i);
                        //cout<<i<<" "<<j<<" "<<k<<" = "<<dp[i][j][k]<<endl;
                    }
                    //else dp[i][j][now]=dp[i-1][j-1][now];
                }
            }
        }
        int state=0;
        while(dp[n%2][m][fix-state]==-1&&dp[n%2][m][fix+state]==-1)state++;
        state=dp[n%2][m][fix-state]>dp[n%2][m][fix+state]?(fix-state):(fix+state);
        //cout<<path[n%2][m][state].size()<<endl;
        int ans1=0,ans2=0;
        for(int i=0;i<path[n%2][m][state].size();i++)ans1+=a[path[n%2][m][state][i]],ans2+=b[path[n%2][m][state][i]];
        printf("Jury #%d\n",cas++);
        printf("Best jury has value %d for prosecution and value %d for defence:\n",ans1,ans2);
        for(int i=0;i<path[n%2][m][state].size();i++)
        {
            printf("%d",path[n%2][m][state][i]);
            if(i==path[n%2][m][state].size()-1)printf("\n");
            else printf(" ");
        }
        printf("\n");
    }
}

POJ - 1458

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

char s1[1005],s2[1005];
int dp[1005][1005];
int main()
{
    while(~scanf("%s%s",s1+1,s2+1))
    {
        int len1=strlen(s1+1);
        int len2=strlen(s2+1);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=len1;i++)
        {
            for(int j=1;j<=len2;j++)
            {
                if(s1[i]==s2[j])
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                }
                else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
        cout<<dp[len1][len2]<<endl;
    }
}

POJ - 2533 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

int a[10005],b[10005];
int cnt;
int erfen(int val)
{
    int l=1,r=cnt;
    while(l<=r)
    {
        int m=(l+r)>>1;
        if(val<=b[m])r=m-1;
        else l=m+1;
    }
    //cout<<l<<" "<<r<<endl;
    return l;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)sca(a[i]);
        b[1]=a[1];
        cnt=1;
        for(int i=2;i<=n;i++)
        {
            int pos=erfen(a[i]);
            b[pos]=a[i];
            //cout<<pos<<endl;
            if(pos>cnt)cnt++;
        }
        cout<<cnt<<endl;
    }
}
/*
1 4 2
*/

POJ - 3186 

区间dp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

int dp[2005][2005];
int sum[2005];
int a[2005];
int S(int l,int r)
{
    if(l>r)return 0;
    return sum[r]-sum[l-1];
}

int DP(int l,int r)
{
    if(l>r)return 0;
    if(l==r)return a[l];
    if(dp[l][r]!=0)return dp[l][r];
    else dp[l][r]=max(a[l]+DP(l+1,r)+S(l+1,r),a[r]+DP(l,r-1)+S(l,r-1));
    return dp[l][r];
}

int main()
{
    int n;
    sca(n);
    for(int i=1;i<=n;i++)sca(a[i]);
    for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
    cout<<DP(1,n)<<endl;
}
/*

*/

HDU - 1078

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

int n,k;
int a[105][105];
int dp[105][105];

bool judge(int x,int y,int x1,int y1)
{
    if(x1<1||x1>n||y1<1||y1>n)return false;
    if(a[x1][y1]<=a[x][y])return false;
    return true;
}

int DP(int x,int y)
{
    if(dp[x][y])return dp[x][y];
    int flag=0;
    for(int i=1;i<=2;i++)
    {
        for(int j=-k;j<=k;j++)
        {
            int x1,y1;
            if(i==1)x1=x,y1=y+j;
            if(i==2)y1=y,x1=x+j;
            if(judge(x,y,x1,y1))
            {
                flag=1;
                dp[x][y]=max(dp[x][y],DP(x1,y1));
            }
        }
    }
    if(!flag)dp[x][y]=a[x][y];
    else dp[x][y]+=a[x][y];
    return dp[x][y];
}
int main()
{
    while(cin>>n>>k)
    {
        if(n==-1&&k==-1)break;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)sca(a[i][j]);
        }
        memset(dp,0,sizeof(dp));
        cout<<DP(1,1)<<endl;
    }
}
/*

*/

HDU - 2859

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define mp(x,y) make_pair(x,y)
#define N 1000005
#define O2 __attribute__((optimize("O2")))

char s[1005][1005];
int dp[1005][1005];
O2 int main()
{
    int n;
    while(cin>>n&&n)
    {
        for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
        memset(dp,0,sizeof(dp));
        int x=1,y=n;
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=n;j>=1;j--)
            {
                int x=i,y=j;
                int cnt=0;
                while(x>=1&&x<=n&&y>=1&&y<=n&&s[x][j]==s[i][y])cnt++,x--,y++;
                if(cnt>dp[i-1][j+1])ans=max(ans,dp[i-1][j+1]+1),dp[i][j]=dp[i-1][j+1]+1;
                else ans=max(ans,dp[i][j]),dp[i][j]=cnt;
                //cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
            }
        }
        cout<<ans<<endl;
    }
}

POJ - 3616

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

struct node
{
    int x,y;
    LL w;
    friend bool operator <(node a,node b)
    {
        return a.x==b.x?a.y<b.y:a.x<b.x;
    }
}a[10005];
LL dp[10005];

bool judge(int i,int j)
{
    return a[j].x>=a[i].y;
}
int main()
{
    int n,m,r;
    cin>>n>>m>>r;

    for(int i=1;i<=m;i++)
    {
        sca(a[i].x),sca(a[i].y);
        scanf("%lld",&a[i].w);
        a[i].y+=r;
    }
    sort(a+1,a+1+m);
    LL ans=0;
    for(int i=1;i<=m;i++)dp[i]=a[i].w;

    for(int i=1;i<=m;i++)
    {
        for(int j=i+1;j<=m;j++)
        {
            if(judge(i,j))
            {
                dp[j]=max(dp[j],dp[i]+a[j].w);
                ans=max(ans,dp[j]);
            }
            //cout<<j<<" "<<i<<" "<<dp[i]<<endl;
        }
    }
    cout<<ans<<endl;
}

POJ - 3666 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<cmath>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long
#define N 2005
#pragma G++ optimize(2)
int a[N],b[N];
LL dp[N][N];
void solve(int n,int m)
{
    for(int i=1;i<=n;i++)
    {
        LL tmp=1LL<<60;
        for(int j=1;j<=m;j++)
        {
            tmp=min(tmp,dp[i-1][j]);
            dp[i][j]+=tmp;
            dp[i][j]+=abs(b[j]-a[i]);
            //cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
        }
    }
    LL ans=1LL<<60;
    for(int i=1;i<=m;i++)ans=min(ans,dp[n][i]);
    cout<<ans<<endl;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)sca(a[i]),b[i]=a[i];
    int cnt=0;
    sort(b+1,b+1+n);
    for(int i=1;i<=n;i++)if(i==1||b[i]!=b[i-1])b[++cnt]=b[i];
    solve(n,cnt);
}

猜你喜欢

转载自blog.csdn.net/weixin_40894017/article/details/88976327
今日推荐