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\n",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\n",i,flag[i],v[i]); return 0; }
T4+S4:点这里.
T3:还有问题,咕咕.