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;
}
poj2228

环形运输 复制接后头,明显有单调性

#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;
}
cf 24D

 

posted @ 2018-08-11 09:49  AKCqhzdy  阅读(246)  评论(0编辑  收藏  举报