校内欢乐赛之爆零季 T2

题目:校内欢乐赛之爆零季 T2_第1张图片
思路:费用流吧,,欢快水掉,,不过貌似还有一种神建图?还有一种神dp?都不太会啊,,
很幸运的搞明白了两种神奇的做法,,,
费用流:看成三个块,,,可以看出每个块内至多有k个对吧,,
可以把一种合法解分解为不超过k条不相交路径,,路径端点满足相差至少为n,,,为什么这么想呢?不知道啊,,貌似是大神在搞k = 1时想出来的,,确实k = 1比较好想,,然而怎么证明?反证法好了,,对应啊,,网络流对应一定是合法解,,因为假设不合法,,那么某个n里有多于k个那一定是多于k条路而这不可能啊,,
合法解对应网络流,,,这里i个合法解向第i+k个连,,,对应网络流,,神啊!orz TA orz 韩宵月 orz faebdc
dp:一看啊k好小啊,,可以暴力枚举三个块内选的个数,,(准确的说前两个就可以了)
f d,i,j,k表示,在3个块内前d个,各自已经选了i,j,k个,,然后块内枚举保证了合法,,跨块之间可以判断一下,,,然后由合法的i,j,k转移过来即可啊,,边界非常多,,共8种情况,,,我也是醉了啊,,,我dp真是弱爆了!!!
faebdc 神dp代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 605;
const int M = 11;
int n,m;
int xu[N][3];
int dp[M][M][M];
int ans=-987654321;
int main()
{
    freopen("war.in","r",stdin);
    freopen("war.out","w",stdout);
    int i,j,k,d;
    int s,t;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        scanf("%d",&xu[i][0]);
    for(i=1;i<=n;i++)
        scanf("%d",&xu[i][1]);
    for(i=1;i<=n;i++)
        scanf("%d",&xu[i][2]);
    for(s=0;s<=m;s++)
    {
        for(t=0;t<=m;t++)
        {
            memset(dp,0xc0,sizeof dp);
            dp[0][0][0]=0;
            for(d=1;d<=n;d++)
            {
                for(i=s;i>=0;i--)
                {
                    for(j=t;j>=0;j--)
                    {
                        if(j+s-i>m)
                            continue;
                        for(k=m;k>=0;k--)
                        {
                            if(k+t-j>m)
                                continue;
                            int now=0;
                            if(i)
                            {
                                now+=xu[d][0];
                                if(j)
                                {
                                    now+=xu[d][1];
                                    if(k)
                                    {
                                        now+=xu[d][2];
                                        dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k-1]+now);
                                        now-=xu[d][2];
                                    }
                                    if(k+t-j<m)
                                        dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k]+now);
                                    now-=xu[d][1];
                                }
                                if(j+s-i<m)
                                {
                                    if(k)
                                    {
                                        now+=xu[d][2];
                                        dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k-1]+now);
                                        now-=xu[d][2];
                                    }
                                    dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]+now);
                                }
                                now-=xu[d][0];
                            }
                            if(j)
                            {
                                now+=xu[d][1];
                                if(k)
                                {
                                    now+=xu[d][2];
                                    dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k-1]+now);
                                    now-=xu[d][2];
                                }
                                if(k+t-j<m)
                                    dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k]+now);
                                now-=xu[d][1];
                            }
                            if(k)
                            {
                                now+=xu[d][2];
                                dp[i][j][k]=max(dp[i][j][k],dp[i][j][k-1]+now);
                                now-=xu[d][2];
                            }
                        }
                    }
                }
            }
            for(i=0;i<=m;i++)
                ans=max(ans,dp[s][t][i]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(校内欢乐赛之爆零季 T2)