• Codeforces Round #206 (Div. 1)B(记忆化)


    这题刚开始理解错题意了 以为只能往右和下走 

    这题挺好的 看题解看了N久啊 

    二维的DP 第一维表示走到第几步 可以画一个正方形 以左上角斜着划线 第i步走的点只能是第i条线上的点 而dp的第二维 就表示的第i步可以到达的点的状态 

    另开一个a数组来表示 第i条线上每个字母的状态 

    dp所代表的值就为a与b的差值 以这个来进行选择 进行记忆化

    确定下一步可以到达的字母的状态 是以当前可达的状态&下一步所要到达的字母的状态 

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 #include<vector>
     7 using namespace std;
     8 #define LL __int64
     9 #define INF 1e9
    10 int dp[42][1<<20],a[42][42];
    11 char s[22][22];
    12 int n;
    13 int dfs(int step,int sta)
    14 {
    15     int i,num=0;
    16     if(dp[step][sta]!=INF)
    17     return dp[step][sta];
    18     for(i = 0; i < n ; i++)
    19     {
    20         if(sta&(1<<i))
    21         {
    22             if(s[step-i][i]=='a') num++;
    23             else if(s[step-i][i]=='b') num--;
    24             break;
    25         }
    26     }
    27     if(step==2*n-2)
    28     return dp[step][sta] = num;
    29     if(step%2!=0)
    30     {
    31         dp[step][sta] = -INF;
    32         for(i = 0 ; i < 26 ; i++)
    33         {
    34             int next = a[step+1][i]&(sta|(sta<<1));
    35             if(next==0)
    36             continue;
    37             dp[step][sta] = max(dp[step][sta],dfs(step+1,next)+num);
    38         }
    39         return dp[step][sta];
    40     }
    41     else
    42     {
    43         for(i = 0 ; i < 26 ; i++)
    44         {
    45             int next = a[step+1][i]&(sta|(sta<<1));
    46             if(next==0)
    47             continue;
    48             dp[step][sta] = min(dp[step][sta],dfs(step+1,next)+num);
    49         }
    50         return dp[step][sta];
    51     }
    52 }
    53 int main()
    54 {
    55     int i,j;
    56     scanf("%d",&n);
    57     for(i = 0 ; i < n ; i++)
    58     cin>>s[i];
    59     for(i = 0 ; i < 2*n-1 ; i++)
    60     {
    61         for(j = 0 ; j < n ; j++)
    62         {
    63             if(i-j<0||i-j>=n) continue;
    64             a[i][s[i-j][j]-'a'] |= (1<<j);
    65         }
    66     }
    67     for(i = 0 ; i < 2*n ; i++)
    68         for(j = 0 ; j < (1<<n) ; j++)
    69         dp[i][j] = INF;
    70     int ans = dfs(0,1);
    71     if(ans>0)
    72     puts("FIRST");
    73     else if(ans<0)
    74     puts("SECOND");
    75     else
    76     puts("DRAW");
    77     return 0;
    78 }
    View Code

  • 相关阅读:
    2015网易校招Java开发工程师(技术架构)在线笔试题
    2015百度校招用户行为分析研发工程师笔试题
    2016届百度实习生前端笔试题上海卷a
    数据库 三范式最简单最易记的解释
    从几个sample来学习JAVA堆、方法区、JAVA栈和本地方法栈
    C++中虚函数和纯虚函数的总结
    MFC一些基本控件操作的总结
    单文档多视图一些基本操作
    MFC单文档静态分割视图
    iOS通讯录相关知识-浅析
  • 原文地址:https://www.cnblogs.com/shangyu/p/3378975.html
Copyright © 2020-2023  润新知