0x55 环形与后效性问题
poj2228 分第一天是否熟睡DP两次
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int n,B,ans,a[4100],f[2][4100][2]; void DP1() { int now=1; memset(f[now],-63,sizeof(f[now])); f[now][0][0]=f[now][1][1]=0; for(int i=2;i<=n;i++) { now^=1; memset(f[now],-63,sizeof(f[now])); f[now][0][0]=0; for(int j=1;j<=min(i,B);j++) { f[now][j][0]=max(f[now^1][j][0],f[now^1][j][1]); f[now][j][1]=max(f[now^1][j-1][0],f[now^1][j-1][1]+a[i]); } } ans=max(ans,max(f[now][B][0],f[now][B][1])); } void DP2() { int now=1; memset(f[now],-63,sizeof(f[now])); f[now][1][1]=a[1]; for(int i=2;i<=n;i++) { now^=1; memset(f[now],-63,sizeof(f[now])); for(int j=1;j<=min(i,B);j++) { f[now][j][0]=max(f[now^1][j][0],f[now^1][j][1]); if(j!=1)f[now][j][1]=max(f[now^1][j-1][0],f[now^1][j-1][1]+a[i]); } } ans=max(ans,f[now][B][1]); } int main() { scanf("%d%d",&n,&B); for(int i=1;i<=n;i++)scanf("%d",&a[i]); ans=0;DP1();DP2(); printf("%d\n",ans); return 0; }
环形运输 复制接后头,明显有单调性
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int a[2100000],q[2100000]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(i!=n)a[i+n]=a[i]; } int head=1,tail=1,mmax=0;q[1]=1; for(int i=2;i<=2*n-1;i++) { while(head<tail&&i-q[head]>n/2)head++; mmax=max(mmax,a[i]+a[q[head]]+i-q[head]); while(head<=tail&&a[i]>=a[q[tail]]+i-q[tail])tail--; q[++tail]=i; } printf("%d\n",mmax); return 0; }
cf 24D 这是有后效性的题,解个方程咯,这里是两个二元其他三元那就左往右一个个消,实在元素多就gauss咯
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> using namespace std; double a[1100],b[1100],f[1100][1100]; int main() { int n,m,stx,sty; scanf("%d%d%d%d",&n,&m,&stx,&sty); if(m==1) { a[n]=0;for(int i=n-1;i>=stx;i--)a[i]=a[i+1]+2; printf("%.4lf\n",a[stx]); return 0; } for(int i=1;i<=m;i++)f[n][i]=0; for(int i=n-1;i>=stx;i--) { a[1]=1.0/2.0; b[1]=(f[i+1][1]+3.0)/2.0; for(int j=2;j<m;j++) { a[j]=1.0/(3.0-a[j-1]); b[j]=(f[i+1][j]+b[j-1]+4.0)/(3.0-a[j-1]); } f[i][m]=(b[m-1]+f[i+1][m]+3.0)/(2.0-a[m-1]); for(int j=m-1;j>=1;j--)f[i][j]=a[j]*f[i][j+1]+b[j]; } printf("%.4lf\n",f[stx][sty]); return 0; }
pain and happy in the cruel world.