zoukankan      html  css  js  c++  java
  • hihocoder 1475数组分拆

    #1475 : 数组分拆

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    小Ho得到了一个数组作为他的新年礼物,他非常喜欢这个数组!

    在仔细研究了几天之后,小Ho成功的将这个数组拆成了若干段,并且每段的和都不为0!

    现在小Ho希望知道,这样的拆分方法一共有多少种?

    两种拆分方法被视作不同,当且仅当数组断开的所有位置组成的集合不同。

    输入

    每组输入的第一行为一个正整数N,表示这个数组的长度

    第二行为N个整数A1~AN,描述小Ho收到的这个数组

    对于40%的数据,满足1<=N<=10

    对于100%的数据,满足1<=N<=105, |Ai|<=100

    输出

    对于每组输入,输出一行Ans,表示拆分方案的数量除以(109+7)的余数。

    样例输入
    5
    1 -1 0 2 -2
    样例输出
    5

    首先想到O(n^2)的dp,dp[i] += dp[j] , j < i && sum[i] != sum[j]
    优化一下就可得到o(n)的算法,先加上再减去.


    //http://www.cnblogs.com/IMGavin/
    //https://hihocoder.com/problemset/problem/1475
    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <bitset>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    #define gets(A) fgets(A, 1e8, stdin)
    const int INF = 0x3F3F3F3F, N = 100008, MOD = 1000000007;
    const int M = 20000008;
    const int P = 1e7;
    const double EPS = 1e-6;
    int a[N];
    LL dp[N];
    LL ds[N];
    
    LL sum[N];
    int tot = 0;
    int s2[M];
    
    int main(){
    	int n;
    	cin >> n;
    	for(int i = 1; i <= n; i++){
    		scanf("%d", &a[i]);
    		sum[i] = sum[i -1] + a[i];
    	}
    	dp[0] = 1;
    	ds[0] = 1;
    	s2[10000000] = 1;
    	for(int i = 1; i <= n; i++){
    		dp[i] = (ds[i - 1] - s2[sum[i] + 10000000] + MOD) % MOD;
    		(s2[sum[i] + 10000000] += dp[i]) %= MOD;
    		ds[i] = (ds[i - 1] + dp[i]) % MOD;
    	}
    	cout<<dp[n]<<endl;
    	return 0;
    }
    

      



  • 相关阅读:
    使用Fiddler捕获Java程序中的HTTP请求
    js解析json对象和json字符串
    写代码 在与思考
    sql 逻辑读取次数
    WbeAPI 学习笔记
    大话设计模式阅读笔记
    行转列
    sql server 的多表查询(left join )
    union 和union all比较
    sql 跨库和域插入数据库
  • 原文地址:https://www.cnblogs.com/IMGavin/p/6724937.html
Copyright © 2011-2022 走看看