• UVA 10118 Free Candies(记忆化搜索)


    这道题像了很长时间才想明白了思路,没有明显的边界状态,状态转移也不能仅仅依靠一个dp数组。

      dp[i][j][k][l] 代表四堆糖果分别拿了ijkl个还能拿到的最多糖果对数(是还能拿到,不算已经拿到的),can数组存储题目输入给出的糖果,top数组表示四堆糖果都拿到了第几个(就是为了简化代码),递推边界为count_bits(S) == 5 或者所有的糖果都被拿光 count_bits计算的是一个数二进制有多少位是1

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<map>
     6 #include<set>
     7 #include<vector>
     8 #include<iostream>
     9 #define PB push_back
    10 #define POB pop_back
    11 #define PII pair<int, int>
    12 #define PDD pair<double, double>
    13 #define rep(i, a, b) for(int i = a ; i < b ; i++)
    14 #pragma comment(linker, "/STACK:1024000000,1024000000")
    15 #ifdef WIN32
    16 #define INT64 "%I64d"
    17 #define UINT64 "%I64u"
    18 #else
    19 #define INT64 "%lld"
    20 #define UINT64 "%llu"
    21 #endif
    22 typedef long long LL;
    23 typedef unsigned long long ULL;
    24 using namespace std;
    25 const int maxn = 41;
    26 int dp[maxn][maxn][maxn][maxn];
    27 int can[maxn][4]; int top[5];
    28 int n;
    29 inline int count_bits(int x){
    30     x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
    31     x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
    32     x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4);
    33     x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8);
    34     x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);
    35     return x;
    36 }
    37 int DP(int S) { //S 表示篮子里的糖果
    38     int& cnt = dp[top[0]][top[1]][top[2]][top[3]];
    39     if(cnt != -1) return cnt;
    40     if(count_bits(S) == 5) return cnt = 0;
    41     for(int i = 0 ; i < 4 ; i++) {
    42         if(top[i] >= n) continue;
    43         top[i]++;
    44         int t = 1 << can[top[i]][i];
    45         if(S & t) cnt = max(cnt, DP(S & (~t)) + 1);
    46         else cnt = max(cnt, DP(S | t));
    47         top[i]--;
    48     }
    49     return cnt = max(cnt, 0);
    50 }
    51 int main()
    52 {
    53     while(scanf("%d", &n) == 1 && n) {
    54         memset(dp, -1, sizeof dp);
    55         memset(top, 0, sizeof top);
    56         for(int i = 1 ; i <= n ; i++)
    57             for(int j = 0 ; j < 4 ; j++)scanf("%d", &can[i][j]);
    58         printf("%d
    ", DP(0));
    59     }
    60     return 0;
    61 }
  • 相关阅读:
    Redis(二)
    Redis
    Nginx
    Linux的环境配置
    深入mysql
    SpringBoot入门
    Thymeleaf入门
    Mybatis之resultMap
    Mybatis入门
    使用第三方实现微信登录
  • 原文地址:https://www.cnblogs.com/tooyoungtoosimple/p/4772385.html
Copyright © 2020-2023  润新知