• 暑假集训Day6 A(动态规划)


    题目链接在这里:Problem - A - Codeforces

    第一眼以为是大讨论,但是自己想感觉根本无从下手,于是考虑了这种动态规划的方法,注意,此题如果按照当前状态由哪些前驱状态推得来动归的话会极其麻烦,因为并不能确定上一个状态是什么样子。所以考虑由当前状态去推到后继状态。

    很显然这里有两种情况,一种是直接到25就胜,一种是必须比另一个高两分才胜。根据这两种情况枚举状态就行。

    这道题需要学习的一个是这种状态定义的方法,每一维表示一种状态;状态转移的过程需要写成由当前状态推到后继状态,这在状态转移的途径很多且不确定的时候需要用这种写法;通过vector容器记录路径的方法,并且要注意在路径合并的过程中由于答案不唯一,所以每个节点只能被访问一次,否则路径会记混。

     1 #include "bits/stdc++.h"
     2 using namespace std;
     3 const int MAX=205;
     4 int t,a,b,f[5][5][MAX][MAX];
     5 vector <pair<int,int> > vec[5][5][MAX][MAX];
     6 int main(){
     7     freopen ("a.in","r",stdin);
     8     freopen ("a.out","w",stdout);
     9     int i,j,c,v,k,win;
    10     scanf("%d",&t);
    11     memset(f,0,sizeof(f));
    12     f[0][0][0][0]=1;
    13     for (i=0;i<=2;i++)
    14         for (j=0;j<=2;j++)
    15             for (c=0;c<MAX;c++)
    16                 for (v=0;v<MAX;v++){
    17                     if (i==2 && j==2) win=15;
    18                     else win=25;
    19                     for (k=win-1;k<MAX;k++){
    20                         if (f[i][j][c][v] && !f[i+1][j][c+k+2][v+k] && c+k+2<MAX && v+k<MAX){
    21                             f[i+1][j][c+k+2][v+k]=f[i][j][c][v];
    22                             vec[i+1][j][c+k+2][v+k]=vec[i][j][c][v];
    23                             vec[i+1][j][c+k+2][v+k].push_back(make_pair(k+2,k));
    24                         }
    25                         if (f[i][j][c][v] && !f[i][j+1][c+k][v+k+2] && c+k<MAX && v+k+2<MAX){
    26                             f[i][j+1][c+k][v+k+2]=f[i][j][c][v];
    27                             vec[i][j+1][c+k][v+k+2]=vec[i][j][c][v];
    28                             vec[i][j+1][c+k][v+k+2].push_back(make_pair(k,k+2));
    29                         }
    30                     }
    31                     for (k=0;k<=win-2;k++){
    32                         if (f[i][j][c][v] && !f[i+1][j][c+win][v+k] && c+win<MAX && v+k<MAX){
    33                             f[i+1][j][c+win][v+k]=f[i][j][c][v];
    34                             vec[i+1][j][c+win][v+k]=vec[i][j][c][v];
    35                             vec[i+1][j][c+win][v+k].push_back(make_pair(win,k));
    36                         }
    37                         if (f[i][j][c][v] && !f[i][j+1][c+k][v+win] && c+k<MAX && v+win<MAX){
    38                             f[i][j+1][c+k][v+win]=f[i][j][c][v];
    39                             vec[i][j+1][c+k][v+win]=vec[i][j][c][v];
    40                             vec[i][j+1][c+k][v+win].push_back(make_pair(k,win));
    41                         }
    42                     }
    43                 }    
    44     while (t--){
    45         scanf("%d%d",&a,&b);
    46         if (f[3][0][a][b]){
    47             printf("3:0\n");
    48             for (i=0;i<vec[3][0][a][b].size();i++)
    49                 printf("%d:%d ",vec[3][0][a][b][i].first,vec[3][0][a][b][i].second);
    50             printf("\n");
    51         }
    52         else if (f[3][1][a][b]){
    53             printf("3:1\n");
    54             for (i=0;i<vec[3][1][a][b].size();i++)
    55                 printf("%d:%d ",vec[3][1][a][b][i].first,vec[3][1][a][b][i].second);
    56             printf("\n");
    57         }
    58         else if (f[3][2][a][b]){
    59             printf("3:2\n");
    60             for (i=0;i<vec[3][2][a][b].size();i++)
    61                 printf("%d:%d ",vec[3][2][a][b][i].first,vec[3][2][a][b][i].second);
    62             printf("\n");
    63         }
    64         else if (f[2][3][a][b]){
    65             printf("2:3\n");
    66             for (i=0;i<vec[2][3][a][b].size();i++)
    67                 printf("%d:%d ",vec[2][3][a][b][i].first,vec[2][3][a][b][i].second);
    68             printf("\n");
    69         }
    70         else if (f[1][3][a][b]){
    71             printf("1:3\n");
    72             for (i=0;i<vec[1][3][a][b].size();i++)
    73                 printf("%d:%d ",vec[1][3][a][b][i].first,vec[1][3][a][b][i].second);
    74             printf("\n");
    75         }
    76         else if (f[0][3][a][b]){
    77             printf("0:3\n");
    78             for (i=0;i<vec[0][3][a][b].size();i++)
    79                 printf("%d:%d ",vec[0][3][a][b][i].first,vec[0][3][a][b][i].second);
    80             printf("\n");
    81         }
    82         else printf("Impossible\n");
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    石子游戏2
    礼物的最大价值
    CF512D. Fox And Travelling
    arc099F
    CF504E. Misha and LCP on Tree(长链剖分求k级祖先)
    agc031D
    CF555E. Case of Computer Network
    agc023D
    CF1406E. Deleting Numbers
    CF585F. Digits of Number Pi
  • 原文地址:https://www.cnblogs.com/keximeiruguo/p/16467911.html
Copyright © 2020-2023  润新知