The 10th UESTC Programming Contest Final [D hours]

本题大意:有一条点,第i点与第i+1点之间有路i,第k次走过路i获得的愉悦值是ai-(k-1)*bi,保证愉悦值为正,求如何走可以使得愉悦值最大

分析:考虑起点i和重点j,可以假设i<=j,那么i左边的路必定走过偶数次,j右边的路必定走过偶数次,i与j之间的路必定走过奇数次,然后DP即可。

#include<stdio.h>
#include<iostream>
#include<string.h>

using namespace std;

const int oo=100000000;

int f[200][200][200],g[200][200],h[200][200],a[200],b[200],c[200][200];

int main()
{
    int num;
    scanf("%d",&num);    
    for (int time=1; time<=num; time++)
    {
        int i,j,k,t,n,d;
        scanf("%d%d",&n,&d);    
        for (i=0; i<n; i++)
        {
            scanf("%d%d",&a[i],&b[i]);
            c[i][0]=0;
            for (j=1; j<=d; j++)
                c[i][j]=a[i]-(j-1)*b[i]+c[i][j-1];
        }
        for (i=0; i<=n; i++)
            for (j=0; j<=n; j++)
                for (k=0; k<=d; k++)
                    {
                          f[i][j][k]=-oo;
                          g[i][k]=-oo;
                          h[j][k]=-oo;
                    }
        for (i=0; i<n; i++)
            for (j=1; j<=d; j+=2)
                f[i][i+1][j]=c[i][j];
        for (i=2; i<=n; i++)
            for (j=0; j+i<=n; j++)
                for (k=i; k<=d; k+=2)
                    for (t=1; (k-t)>=i-1; t+=2)
                        if (f[j][j+i][k]<f[j+1][j+i][k-t]+c[j][t])
                           f[j][j+i][k]=f[j+1][j+i][k-t]+c[j][t];
        for (i=2; i<=d; i+=2) {g[1][i]=c[0][i]; h[n-1][i]=c[n-1][i];}
        for (i=1; i<=n; i++) {g[i][0]=0; h[n-i][0]=0; f[i][i][0]=0;}
        f[0][0][0]=0;
        for (i=2; i<=n; i++)
            for (j=2; j<=d; j+=2)
                for (k=2; k<=j; k+=2)
                {
                    if (g[i][j]<g[i-1][j-k]+c[i-1][k])
                       g[i][j]=g[i-1][j-k]+c[i-1][k];
                    if (h[n-i][j]<h[n-i+1][j-k]+c[n-i][k])
                       h[n-i][j]=h[n-i+1][j-k]+c[n-i][k];
                }
        int ans=-oo;
        for (i=0; i<=n; i++)
            for (j=i; j<=n; j++)
                for (k=0; k<=d; k+=2)
                    for (t=0; t+k<=d; t+=2)
                        if (ans<g[i][k]+h[j][t]+f[i][j][d-k-t])
                           ans=g[i][k]+h[j][t]+f[i][j][d-k-t];
        cout<<"Case #"<<time<<": "<<ans<<endl;
    }
    return 0;
}

  

posted @ 2012-05-11 21:39  ustc-acm  阅读(405)  评论(0编辑  收藏  举报