• 第五届华中区程序设计邀请赛暨武汉大学第十四届校赛 网络预选赛 E Calculation 状态压缩DP枚举子集


    Problem 1608 - Calculation
     
    Description
    Today, Alice got her math homework again!
    She had n integers, and she needed to divide them into several piles or one pile. For each pile, if the teacher could get Sby + or – operator, then Alice got 1 small red flower. Alice wanted to get as many flowers as possible. Could you help her? Just tell her the maximum number of flowers she could get.
    Input
    The input consists of several test cases.
    The first line consists of one integer T (T <= 100), meaning the number of test cases.
    The first line of each test cases consists of two integer n (n<=14), meaning the number of the integer, and S (0<= S<= 100000000), meaning the result which teacher wanted.
    The next line consists of n integer a1, a2, …, an (0<= ai <= 10000000).
    You should know a few cases that n is larger than 12.
    Output
    For each test case, output one line with one integer without any space.
    Sample Input
    2
    5 5
    1 2 3 4 5
    5 5
    1 2 3 8 8
    Sample Output
    3
    2
     
    题意:
     
       给你n个数和S,
       让你把这N个数分成任意个集合块,集合块内可以通过任意加减 得到一个值,假如这个值等于S,则答案加一,问最大是多少
     
    题解:
        
       N的范围是小于14
      容易想到状态压缩,
      我们就预处理出 每个子集 取的数的和 也就是全取正
      再通过不断取负号 为什么不用 不取的情况,因为子集会包含在内
      最后dp统计答案就好无聊
     
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    const int N = 1e5+10, M = 50, mod = 1e9+9, inf = 1e9+9;
    typedef long long ll;
    
    
    int dp[1<<15],n,m,a[N],b[N ],c[N];
    int main() {
        int T;
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++) scanf("%d",&a[i]);
            for(int i=0;i<(1<<n);i++) {
                    b[i] = 0;dp[i] = 0;c[i] = 0;
                for(int j=0;j<n;j++) {
                    if(i&(1<<j)) b[i]+=a[j];
                }
            }
            for(int i=0;i<(1<<n);i++) {
                if(b[i]==m) c[i]=1;
                for(int j=i;j;j = (j-1)&i) {
                    if(c[j]) {c[i] = 1;break;}
                  if(b[i]-b[j]-b[j]==m) {c[i] =1;break;}
                }
            }
            for(int i=0;i<(1<<n);i++) {
                dp[i] = 0;
                for(int j=i;j;j = (j-1)&i) {
                    if(c[j]) dp[i] = max(dp[i], dp[i^j] + 1);
                }
            }
            printf("%d
    ",dp[(1<<n)-1]);
        }
        return 0;
    }
  • 相关阅读:
    SSM框架--详细整合教程
    ssh--整合注意事项
    SSH--三大框架整合原理
    springMVC的流程
    java框架问题整理
    集合的体系
    java异常机制
    java知识点
    Java编程思想【Thinking in java】
    实验三 指令实验(一)
  • 原文地址:https://www.cnblogs.com/zxhl/p/5372337.html
Copyright © 2020-2023  润新知