全部评论 3

  • 我把f的结果输出出来比对发现f[2][12]应该是0但是值为3,违反了相邻不能坐的规则

    if (presub >> 1 & (presub | sub) || presub << 1 & (presub | sub)) continue;
    

    应改成

    if (sub >> 1 & (presub | sub) || sub << 1 & (presub | sub)) continue;
    

    话说这些条件里面做运算的看的累死人,最好写的容易理解一点,避免判断多种运算符优先级

    2024-06-20 来自 浙江

    0
    • ####果然是!!,测试点留了钻空子的机会,判断是否是完全背包就直接能跑完全背包了
      ###单调队列优化&预处理是否是完全背包问题
      ####运行时间160ms

      #include <stdio.h>
      #include <stdlib.h>
      #define arraymax 20001
      #define Max(a, b) (a > b ? a : b)
      int dp[arraymax];
      int book[arraymax], que[arraymax];
      int main(int argc, char *argv[])
      {
          int n, m;
          scanf("%d%d", &n, &m);
          while (n--)
          {
              int k, value, cnt;
              scanf("%d%d%d", &k, &value, &cnt);
              if (cnt * k >= m)
              {
                  for (int ind = k; ind <= m; ind++)
                      dp[ind] = Max(dp[ind - k] + value, dp[ind]);
              }
              else
              {
                  for (int ind = 0; ind < k; ind++)
                  {
                      int head = 0, body = 0;
                      for (int jnd = 0; jnd <= (m - ind) / k; jnd++)
                      {
                          int y = dp[jnd * k + ind] - jnd * value;
                          while (head < body && y >= que[body - 1])
                              body--;
                          book[body] = jnd;
                          que[body++] = y;
                          if (book[head] < jnd - cnt)
                              head++;
                          dp[jnd * k + ind] = que[head] + jnd * value;
                      }
                  }
              }
          }
          printf("%d\n", dp[m]);
          return 0;
      }
      

      2024-06-20 来自 浙江

      0
    • 标题1

      标题2

      2024-06-20 来自 浙江

      0
    • class Solution {
      public:
          int maxStudents(vector<vector<char>>& seats) {
              int m = seats.size(), n = seats[0].size(), ans = 0;
              vector<int>seq(m + 1);//第一排前面加一排,用于更新第一排的状态
              for (int i = 0; i < m; i++)
                  for (char c : seats[i])
                      seq[i + 1] = (seq[i + 1] << 1) | (c == '.');//所有完好座位的集合
              vector<vector<int>>f(1 << n, vector<int>(m + 1));
              for (int i = 0; i < m; i++){
                  int sub = seq[i + 1];//枚举第i+1行所有完好座位的子集
                  do{
                      int presub = seq[i], count = __builtin_popcount(sub);//枚举第i行所有完好座位的子集
                      do{
                          if (presub >> 1 & (presub | sub) || presub << 1 & (presub | sub)) continue;//左侧、右侧、左上、右上有人
                          f[sub][i + 1] = max(f[sub][i + 1], f[presub][i] + count);
                      }while((presub = (presub - 1) & seq[i]) | 1 && presub != seq[i]);//枚举第i行所有完好座位的子集,|1是防止空集为0会使while里判断错误
                  }while((sub = (sub - 1) & seq[i + 1]) | 1 && sub != seq[i + 1]);//枚举第i+1行所有完好座位的子集,|1是防止空集为0会使while里判断错误
              }
              for (int i = 0; i < 1 << n; i++) ans = max(ans, f[i][m]);
              return ans;
          }
      };
      

      2024-06-20 来自 浙江

      0
  • 我把f的结果输出出来比对发现f[2][12]应该是0但是值为3,违反了相邻不能坐的规则

    
    if (presub >> 1 & (presub | sub) || presub << 1 & (presub | sub)) continue;
    
    

    应改成

    
    if (sub >> 1 & (presub | sub) || sub << 1 & (presub | sub)) continue;
    

    话说这些条件里面做运算的看的累死人,最好写的容易理解一点,避免判断多种运算符优先级

    2024-06-20 来自 浙江

    0