CSU1207(Strictly-increasing sequence)

来源:互联网 发布:网络课程app 编辑:程序博客网 时间:2024/05/27 16:41

1207: Strictly-increasing sequence

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 371  Solved: 84
[Submit][Status][Web Board]

Description

如果一个序列中任意一项都大于前一项,那么我们就称这个序列为严格递增序列。

现在有一个整数序列,你可以将序列中任意相邻的若干项合并成一项,合并之后这项的值为合并前各项的值之和。通过若干次合并,最终一定能得到一个严格递增序列,那么得到的严格递增序列最多能有多少项呢?

Input

输入数据的第一行包含正整数T (1 <= T <= 200),表示接下来一共有T组测试数据。

每组测试数据的第一行包含一个整数N (1 <= N <= 1000),表示这个整数序列一共有N项。接下来一行包含N个不大于10^6的正整数,依次描述了这个序列中各项的值。

至多有20组数据满足N > 100

Output

对于每组测试数据,用一行输出一个整数,表示最终得到的严格递增序列最多能有多少项。

Sample Input

321 131 2 351 3 2 6 7

Sample Output

134

题意:略。。

思路:贪心不太好写,应该用动态规划写。

dp[i](1->n)表示以第i个元素结尾的序列的最大的符合条件的递增个数,开rec数组记录合并的元素之和,sum数组记录1->i的和,两个for循环,外循环i(1->n),内循环j(1->i-1),枚举j->i的元素合并的情况,更新i位置的rec数组值,有状态转移方程:dp[i]=min(dp[i],dp[j]+1),(sum[i]-sum[j]>rec[j]);


#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int INF=1<<30;int a[1005],sum[1005],rec[1005];int dp[1005];int main(){    int t;    scanf("%d",&t);    while(t--){        int n;        scanf("%d",&n);        sum[0]=rec[0]=0;        for(int i = 1; i <= n; i++){            scanf("%d",&a[i]);            rec[i]=INF;            if(i==1)sum[i]=a[i];            else sum[i]=sum[i-1]+a[i];        }        memset(dp,0,sizeof(dp));        for(int i = 1; i <= n; i++){            for(int j = 0; j < i; j++){                 if(sum[i]-sum[j]>rec[j]){                    if(dp[i]<=dp[j]+1){                        dp[i]=dp[j]+1;                        rec[i]=min(rec[i],sum[i]-sum[j]);                    }                 }            }        }        printf("%d\n",dp[n]);    }    return 0;}



0 0
原创粉丝点击