DP套题练习4

.T1:给定两个字符串,求最长公共子序列.

S1:板子题,直接上code.

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define R register
char s[5010],t[5010];
int lens,lent,f[5010][5010];
int main()
{    
    freopen("lcs.in","r",stdin);
    freopen("lcs.out","w",stdout);
    scanf("%s",s+1),scanf("%s",t+1);
    lens=strlen(s+1),lent=strlen(t+1);
    for(R int i=1;i<=lens;++i)
        for(R int j=1;j<=lent;++j)
        {    
            if(s[i]==t[j])
                f[i][j]=f[i-1][j-1]+1;
            else if(s[i]!=t[j])
                f[i][j]=max(f[i][j-1],f[i-1][j]);
        }
    printf("%d",f[lens][lent]);
    return 0;
}

S2:显然我们可以看出这是一个线性DP.我们设f[ i ][ j ]表明过完了i年,当前使用的卡车用了j年.当j ! = 1时,f[ i ][ j ] = f[ i-1 ][ j-1 ] + R[ j -1 ] -U[ j - 1].当j = =1时,我们要枚举i-1年的卡车状态k,f[ i ][ 1 ] = f[ i -1 ][ k ]+R[ 0 ] - U[ 0 ] - C[ k ].注意第一年就是'0'年的新车,f[ 1 ][ 1 ] = R[ 0 ] - U[  0 ].最后记录转移节点,用前驱数组记录即可.

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
int n,k,lx,ly,lastr[24][24][2],flag[24];
double ans,lr[24],wx[24],hc[24],f[24][24],v[24];
int main()
{
    freopen("truck.in","r",stdin);
    freopen("truck.out","w",stdout);
    scanf("%d",&n),scanf("%d",&k);
    for(re int i=0;i<=k;++i)
        scanf("%lf",&lr[i]);
    for(re int j=0;j<=k;++j)
        scanf("%lf",&wx[j]);
    for(re int g=0;g<=k;++g)    
        scanf("%lf",&hc[g]);
    for(re int i=0;i<24;++i)
        for(re int j=0;j<24;++j)
            f[i][j]=-19260817.0;
    f[1][1] = lr[0] -wx[0];
    for(re int i=2;i<=n;++i)
        for(re int j=1;j<=k;++j){
            if(j!=1)
                f[i][j] = max( f[i][j],f[i-1][j-1] + lr[j-1]-wx[j-1]);
            else for(re int l=1;l<=k;++l)
                f[i][j] = max(f[i][j],f[i-1][l]+ lr[0] - wx[0] - hc[l]);
        }
    for(re int i=1;i<=k;++i)
        ans=max(ans,f[n][i]);
    printf("%.1lf
",ans);
    memset(lastr,-1,sizeof(lastr));
    for(re int i=n;i>=1;--i)
        for(re int j=1;j<=k;++j){
            if(j!=1&&f[i][j]==f[i-1][j-1]+lr[j-1]-wx[j-1])
                lastr[i][j][0]=i-1,lastr[i][j][1]=j-1;
            else if(j==1){
                for(re int l=1;l<=k;++l)
                    if(f[i][j]==f[i-1][l]+lr[0]-wx[0]-hc[l])
                        lastr[i][j][0]=i-1,lastr[i][j][1]=l;
            }
        }
    for(re int i=1;i<=k;++i)
        if(ans==f[n][i])
            lx=n,ly=i;
    v[n]=ans;
    if(ly==1) flag[n]=1;
    else flag[n]=0;
    lx=lastr[lx][ly][0],ly=lastr[lx][ly][1];
    while(lx!=-1&&ly!=-1){
        v[lx]=f[lx][ly];
        if(ly==1) flag[lx]=1;
        else flag[lx]=0;
        int nowx=lx,nowy=ly;
        lx=lastr[nowx][nowy][0],ly=lastr[nowx][nowy][1];
    }
    flag[1]=0;
    for(re int i=n;i>=2;--i)
        v[i]=v[i]-v[i-1];
    for(re int i=1;i<=n;++i)
        printf("%d %d %.1lf
",i,flag[i],v[i]);
    return 0;
}

T4+S4:点这里.

T3:还有问题,咕咕.

原文地址:https://www.cnblogs.com/xqysckt/p/11415030.html