zoukankan      html  css  js  c++  java
  • 计蒜客——等和的分隔子集

    原题链接:https://nanti.jisuanke.com/t/28

    题目

    晓萌希望将1到N的连续整数组成的集合划分成两个子集合,且保证每个集合的数字和是相等。例如,对于N=3,对应的集合{1,2,3}能被划分成{3} 和 {1,2}两个子集合.

    这两个子集合中元素分别的和是相等的。

    对于N=3,我们只有一种划分方法,而对于N=7时,我们将有4种划分的方案。

    输入包括一行,仅一个整数,表示N的值(1≤N≤39)。

    输出包括一行,仅一个整数,晓萌可以划分对应N的集合的方案的个数。当没发划分时,输出0。

    样例输入

    7

    样例输出

    4
    /*
     * 思路
     * 1、总和为奇数,那么划分的方案数为0
     * 2、总和为偶数,假设每部分的和为m。直接暴力枚举:从1~n,看能否凑成需要的和m,当这个数小于m的时候,才有可能
     *     是和的一部分,那么就两种情况,递归求解。
     * 3、因为在两种情况下存在重复计算的情况,就使用动态规划的思想用一个数组,把计算过的保存下来。
     * 4、最后的方案数会比较大,使用long型。
     * 
     * */
    import java.util.*;
    public class 等和的分隔子集 {
        /*n最大为39,所以每一部分的总和最大为390.
         * 初始为0:表示还没有计算过。
         * -1:表示当前情况的方案数为0
         * 整数:表示当前情况的方案值。
         * */
        private static long[][] done=new long[391][391];
        public static void main(String[] args) {
            int n;
            Scanner in=new Scanner(System.in);
            n=in.nextInt();
            System.out.println(solve(n));
        }
        static long solve(int n){
            int count=n*(n+1)/2;
            if(count%2==1){
                return 0;
            }
            count/=2;
            return isOk(n,count,1)/2;
        }
        static long isOk(int scope,int currentCount,int index){
            if(index>scope||currentCount<index){
                done[currentCount][index]=-1;//表示无法获得
                return 0;
            }
            //因为是从小到大的,所以当前找到了,说明后面肯定没有了,返回1.
            if(currentCount==index){
                return 1;
            }
            long a=0;
            if(done[currentCount][index+1]==0){
                a=isOk(scope,currentCount,index+1);
                done[currentCount][index+1]=(a==0?-1:a);
            }else{
                a=done[currentCount][index+1]==-1?0:done[currentCount][index+1];
            }
            long b;
            if(done[currentCount-index][index+1]==0){
                b=isOk(scope,currentCount-index,index+1);
                done[currentCount-index][index+1]=(b==0?-1:b);
            }else{
                b=done[currentCount-index][index+1]==-1?0:done[currentCount-index][index+1];
            }
            return a+b;
        }
    }
  • 相关阅读:
    [原创]c#快速排序类 Virus
    [原创]关系,依赖, Virus
    [原创]外包 Virus
    [原创]异步调用I/O方法的使用 Virus
    [原创]一个查找并且替换的算法 Virus
    封装原来的DirectoryInfo类,添加事件,可以代替FileSystemWatcher 类 Virus
    [原创]包头人在北京<一> Virus
    [原创]异步调用,多线程,委托 Virus
    [原创]异步,跨线程,非阻塞,DNS,Socket Virus
    [原创]大家动脑吧,一个面试题 Virus
  • 原文地址:https://www.cnblogs.com/xiangguoguo/p/9153378.html
Copyright © 2011-2022 走看看