zoukankan      html  css  js  c++  java
  • 第五届华中区程序设计邀请赛暨武汉大学第十四届校赛 网络预选赛 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;
    }
  • 相关阅读:
    类(抽象类与非抽象类)和接口
    Arduino学习——u8glib提供的字体样式
    Arduino学习——u8glib库资料整理
    Arduino学习——Arduino main 函数
    全局变量的初始化
    nmake学习笔记2
    Big Endian与Litter Endian
    nmake学习笔记
    重载操作符
    offsetof的意义
  • 原文地址:https://www.cnblogs.com/zxhl/p/5372337.html
Copyright © 2011-2022 走看看