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;
    }
  • 相关阅读:
    iOS-触摸事件、手势识别、摇晃事件、耳机线控
    iOS-App生命周期
    Foundation框架—时间处理对象NSDate
    Kali linux渗透测试的艺术 思维导图
    数据结构_二叉树遍历
    数据结构_数值转换
    <转载>Mac下,使用sshpass让iterm2支持多ssh登录信息保存
    <转载>iTerm2使用技巧
    Maven打包编译找不到com.sun.crypto.provider.SunJCE类
    MySQL自动设置create_time和update_time
  • 原文地址:https://www.cnblogs.com/zxhl/p/5372337.html
Copyright © 2011-2022 走看看