zoukankan      html  css  js  c++  java
  • 【BZOJ2287】消失之物 [分治][DP]

    消失之物

    Time Limit: 10 Sec  Memory Limit: 128 MB
    [Submit][Status][Discuss]

    Description

      ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN

      由于她的疏忽, 第 i 个物品丢失了.

      “要使用剩下的 N - 1 物品装满容积为 x 的背包,有几种方法呢?” -- 这是经典的问题了。

      她把答案记为 Count(i, x) ,想要得到所有1 <= i <= N, 1 <= x <= M的 Count(i, x) 表格。

    Input

      第1行:两个整数 NM ,物品的数量和最大的容积。
      第2行: N 个整数 W1, W2, ..., WN, 物品的体积。

    Output

      一个 N × M 的矩阵, Count(i, x)的末位数字。

    Sample Input

      3 2
      1 1 2

    Sample Output

      11
      11
      21

    HINT

      1 ≤ N ≤ 2 × 1e3, 1 ≤ M ≤ 2 × 1e3

    Solution

      首先,我们发现,对于L,R:
      去掉L,就是要用[1, L - 1]∪[L + 1, n]的物品来求解;
      去掉R,就是要用[1, R - 1]∪[R + 1, n]的物品来求解。
      若是我们更新完了([1, L - 1]∪[L + 1, n])([1, R - 1]∪[R + 1, n])的部分,
      再加上L的,即是去掉R的答案;再加上R的,即是去掉L的答案。

      那么我们就可以考虑分治
      设计状态Solve(L, R),表示已经做完了[1, L - 1]∪[R + 1, n]时的答案。
      然后二分一个mid = L + R >> 1;
      要处理[L, mid]则将[mid + 1, R]的更新一下,反之同理。
      那么这样我们最后做到L == R时候,显然就是去掉L的答案了。

      DP部分显然就是一个简单的背包。

    Code

     1 #include<iostream>
     2 #include<string>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cmath>
     8 #include<queue>
     9 using namespace std;
    10 typedef long long s64;
    11 
    12 const int ONE = 100005;
    13 const int INF = 2147483640;
    14 
    15 int n, m;
    16 int a[ONE];
    17 int f[20][ONE];
    18 
    19 int get()
    20 {
    21         int res=1,Q=1;  char c;
    22         while( (c=getchar())<48 || c>57)
    23         if(c=='-')Q=-1;
    24         if(Q) res=c-48; 
    25         while((c=getchar())>=48 && c<=57) 
    26         res=res*10+c-48;
    27         return res*Q; 
    28 }
    29 
    30 void Solve(int L, int R, int Dep)
    31 {
    32         if(L == R)
    33         {
    34             for(int j = 1; j <= m; j++)
    35                 printf("%d", f[Dep][j]);
    36             printf("
    ");
    37             return;
    38         }
    39 
    40         int mid = L + R >> 1;
    41 
    42         for(int j = m; j >= 0; j--) f[Dep + 1][j] = f[Dep][j];
    43         for(int i = mid + 1; i <= R; i++)
    44             for(int j = m; j >= 0; j--)
    45                 (f[Dep + 1][j] += f[Dep + 1][j - a[i]]) %= 10;
    46         Solve(L, mid, Dep + 1);
    47 
    48         for(int j = m; j >= 0; j--) f[Dep + 1][j] = f[Dep][j];
    49         for(int i = L; i <= mid; i++)
    50             for(int j = m; j >= 0; j--)
    51                 (f[Dep + 1][j] += f[Dep + 1][j - a[i]]) %= 10;
    52         Solve(mid + 1, R, Dep + 1);
    53 }
    54 
    55 int main()
    56 {
    57         n = get();    m = get();
    58         for(int i = 1; i <= n; i++) a[i] = get();
    59         f[0][0] = 1;
    60         Solve(1, n, 0);
    61 }
    View Code
  • 相关阅读:
    河南六大学生程序设计竞赛--外国人饲喂站
    Basic脚本解释器移植到STM32
    C++ 建设者继承
    数据结构:Binary and other trees(数据结构,算法及应用(C++叙事描述语言)文章8章)
    POJ 2251-Dungeon Master(BFS)
    Python编程预约参观北京行动纲要
    debian防火墙firestarter
    debian清除无用的库文件(清理系统,洁癖专用)
    Linux(Debian) vps安装gnome桌面+VNC
    debian下Vnc
  • 原文地址:https://www.cnblogs.com/BearChild/p/7725524.html
Copyright © 2011-2022 走看看