• Codeforces Round #247 (Div. 2) C. k-Tree (dp)


    题目链接

    自己的dp, 不是很好,这道dp题是 完全自己做出来的,完全没看题解,还是有点进步,虽然这个dp题比较简单。

    题意:一个k叉树, 每一个对应权值1-k, 问最后相加权值为n, 且最大值至少为d 的路径有多少条。

    思路:d[i][l][sum] 表示第i 行最大值为l, 总和为sum的路径数。

    注意:我的代码中 sum + j 有可能会超过数组最大值,即越界,刚开始我以为不会产生影响,后来

    发现不知道为什么 在数组里越界以后比如 越界到d[][][111] 会对 d[][][1]产生影响,还是要注意写代码 不要让数据越界吧。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 using namespace std;
     7 const int mo = 1000000000 + 7;
     8 int dp[110][110][110];
     9 
    10 int main()
    11 {
    12     int n, k, d, i, j, l, sum, ans;
    13     while(cin>>n>>k>>d)
    14     {
    15         memset(dp, 0, sizeof(dp));
    16         for(i = 1; i <= k; i++)
    17             dp[0][i][i] = 1;
    18         for(i = 1; i < n; i++)
    19         {
    20             for(l = 1; l <= k; l++)
    21                 for(sum = 1; sum <= 100; sum++)
    22                 {
    23                     if(dp[i-1][l][sum] == 0)
    24                         continue;
    25                     for(j = 1; j <= k; j++)
    26                     {
    27                         if(sum + j > n)   //注意,不然数组会越界导致结果错误
    28                             break;
    29                         if(j > l)
    30                         {
    31                             dp[i][j][sum+j] += dp[i-1][l][sum];
    32                             dp[i][j][sum+j] %= mo;
    33                         }
    34                         else
    35                         {
    36                             dp[i][l][sum+j] += dp[i-1][l][sum];
    37                             dp[i][l][sum+j] %= mo;
    38 
    39                         }
    40                     }
    41                 }
    42         }
    43             ans = 0;
    44             for(j = 0; j < n; j++)
    45             for(i = d; i <= 100; i++)
    46                 {
    47                     ans += dp[j][i][n];
    48                     ans %= mo;
    49                 }
    50             printf("%d
    ", ans);
    51         }
    52         return 0;
    53     }

    贴一下我找我的越界错误的代码,

    做完题后 我又找了好长时间错误。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 using namespace std;
     7 const int mo = 1000000000 + 7;
     8 int dp[110][110][110];
     9 
    10 int main()
    11 {
    12     int n, k, d, i, j, l, sum, ans, flag;
    13     while(cin>>n>>k>>d)
    14     {
    15         flag = 0;
    16         memset(dp, 0, sizeof(dp));
    17         for(i = 1; i <= k; i++)
    18             dp[0][i][i] = 1;
    19         for(i = 1; i < n; i++)
    20         {
    21             for(l = 1; l <= k; l++)
    22                 {
    23                     for(sum = 1; sum <= 100; sum++)
    24                 {
    25                     if(dp[i-1][l][sum] == 0)
    26                         continue;
    27                     for(j = 1; j <= k; j++)
    28                     {
    29                         /*if(sum + j > n)
    30                             break;*/
    31                         if(j > l)
    32                         {
    33                            printf("%d
    ", dp[1][57][1]);
    34                             dp[i][j][sum+j] += dp[i-1][l][sum];
    35                             dp[i][j][sum+j] %= mo;
    36 
    37                              if(dp[1][57][1])
    38                             {
    39                                 printf("%d %d %d
    ", i, j, sum+j);
    40                                 printf("%d
    ", dp[i][j][sum+j]);
    41                                 printf("%d %d %d
    ", dp[1][57][1], dp[1][57][0], dp[1][57][2]);
    42                                 flag = 1;
    43                                 break;
    44                             }
    45                         }
    46                         else
    47                         {
    48                             dp[i][l][sum+j] += dp[i-1][l][sum];
    49 
    50                             dp[i][l][sum+j] %= mo;
    51 
    52                         }
    53 
    54                         if(flag)
    55                             break;
    56                     }
    57                     if(flag)
    58                         break;
    59                 }
    60                 if(flag)
    61                     break;
    62                 }
    63                 if(flag)
    64                     break;
    65         }
    66             ans = 0;
    67             for(j = 0; j < n; j++)
    68             for(i = d; i <= 100; i++)
    69                 {
    70                     ans += dp[j][i][n];
    71                     ans %= mo;
    72                 }
    73            // printf("%d
    ", ans);
    74         }
    75         return 0;
    76     }
  • 相关阅读:
    网游内存数据库的设计(1)
    基于用户级线程的远程调用效率测试
    实现c协程
    KendyNet for linux
    开源一个lua的网络库
    C语言重写网络发送/接收封包
    C协程使用举例
    各种内存分配器的对比测试
    KendyNet性能测试
    C协程实现的效率对比
  • 原文地址:https://www.cnblogs.com/bfshm/p/3746492.html
Copyright © 2020-2023  润新知