组队赛131006 Regionals 2010, Europe - Southeastern

H题:记忆化dp

dp[i][j]记录i,j这个位置的状态是0,1,表示第一个人遇到此状态的胜败。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 1111
int row[maxn][maxn],col[maxn][maxn];
int dp[maxn][maxn];//表示改点是否是必胜态
int main()
{
    int n,x;
    while(scanf("%d",&n)!=EOF)
    {
        memset(row,0,sizeof(row));
        memset(col,0,sizeof(col));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&x);
                row[i][j]=(row[i][j-1]+x)%2;
                col[i][j]=(col[i-1][j]+x)%2;
            }
        }
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(dp[i-1][j]==0&&row[i][j]==0)
                dp[i][j]=1;
                if(dp[i][j-1]==0&&col[i][j]==0)
                dp[i][j]=1;
            }
        }
        if(dp[n][n])
        {
            printf("W\n");
        }
        else
        {
            printf("L\n");
        }
    }
    return 0;
}
G题:模拟lca的思想。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define eps 1e-10
using namespace std;
int mp[1111][1111],dp[1111][1111];
int main()
{
//    freopen("C:\\Users\\cugbacm\\Desktop\\in.in","r",stdin);
//    freopen("C:\\Users\\cugbacm\\Desktop\\out1.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                scanf("%d",&mp[i][j]);
                mp[j][i]=mp[i][j];
            }
        }
        int ans=mp[1][2]-1;
        for(int i=3;i<=n;i++)
        {
            int tmp=mp[i][1];
            for(int j=2;j<i;j++)
            {
                int t=mp[i][1]-(mp[i][1]+mp[j][1]-mp[i][j])/2;
                if(t<tmp) tmp=t;
            }
            ans+=tmp-1;
        }
        printf("%d\n",ans);
    }
    return 0;
}
F题:图上的dp,枚举每个方向可能取的步数,取最小值。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 1055
#define INF 0x7fffffff
#define ll long long
using namespace std;
char s[maxn];
ll dp[10][4][maxn][maxn];
int mp[maxn][maxn];
int main()
{
    int r,c;
    while(scanf("%d%d",&r,&c)!=EOF)
    {
        int maxc=0,minc=9;
        for(int i=1;i<=r;i++)
        {
            scanf("%s",s);
            int l=strlen(s);
            for(int j=0;j<l;j++)
            {
                mp[i][j+1]=s[j]-'0';
                maxc=max(maxc,mp[i][j+1]);
                minc=min(minc,mp[i][j+1]);
            }
        }
        ll ans=0;
//        memset(dp,0,sizeof(dp));
        for(int k=minc;k<=maxc;k++)
        {
            for(int i=1;i<=r;i++)
            {
                //左上
                for(int j=1;j<=c;j++)
                {
                    dp[k][0][i][j]=INF;
                    if(i>1&&mp[i-1][j]==k)
                    dp[k][0][i][j]=2;
                    if(j>1&&mp[i][j-1]==k)
                    dp[k][0][i][j]=2;
                    if(i>1)
                    {
                        dp[k][0][i][j]=min(dp[k][0][i][j],dp[k][0][i-1][j]+2);
                    }
                    if(j>1)
                    {
                        dp[k][0][i][j]=min(dp[k][0][i][j],dp[k][0][i][j-1]+2);
                    }
                }
                //右上
                for(int j=c;j>=1;j--)
                {
                    dp[k][1][i][j]=INF;
                    if(i>1&&mp[i-1][j]==k)
                    dp[k][1][i][j]=2;
                    if(j<c&&mp[i][j+1]==k)
                    dp[k][1][i][j]=2;
                    if(i>1)
                    {
                        dp[k][1][i][j]=min(dp[k][1][i][j],dp[k][1][i-1][j]+2);
                    }
                    if(j<c)
                    {
                        dp[k][1][i][j]=min(dp[k][1][i][j],dp[k][1][i][j+1]+2);
                    }
                }
            }
            for(int i=r;i>=1;i--)
            {
                //左下
                for(int j=1;j<=c;j++)
                {
                    dp[k][2][i][j]=INF;
                    if(j>1&&mp[i][j-1]==k)
                    dp[k][2][i][j]=2;
                    if(i<r&&mp[i+1][j]==k)
                    dp[k][2][i][j]=2;
                    if(j>1)
                    {
                        dp[k][2][i][j]=min(dp[k][2][i][j],dp[k][2][i][j-1]+2);
                    }
                    if(i<r)
                    {
                        dp[k][2][i][j]=min(dp[k][2][i][j],dp[k][2][i+1][j]+2);
                    }
                }
                //右下
                for(int j=c;j>=1;j--)
                {
                    dp[k][3][i][j]=INF;
                    if(i<r&&mp[i+1][j]==k)
                    {
                        dp[k][3][i][j]=2;
                    }
                    if(j<c&&mp[i][j+1]==k)
                    {
                        dp[k][3][i][j]=2;
                    }
                    if(i<r)
                    {
                        dp[k][3][i][j]=min(dp[k][3][i][j],dp[k][3][i+1][j]+2);
                    }
                    if(j<c)
                    {
                        dp[k][3][i][j]=min(dp[k][3][i][j],dp[k][3][i][j+1]+2);
                    }
                }
            }
            for(int i=1;i<=r;i++)
            {
                for(int j=1;j<=c;j++)
                {
                    ll min_x=INF;
                    for(int l=0;l<4;l++)
                    {
                        min_x=min(min_x,dp[k][l][i][j]);
                    }
                    if(min_x!=INF)
                    ans+=min_x;
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}



你可能感兴趣的:(组队赛131006 Regionals 2010, Europe - Southeastern)