DP-HDU-5773-The All-purpose Zero

2023-10-17 07:08
文章标签 dp hdu zero purpose 5773

本文主要是介绍DP-HDU-5773-The All-purpose Zero,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

The All-purpose Zero

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 279 Accepted Submission(s): 129

Problem Description
?? gets an sequence S with n intergers(0 < n <= 100000,0<= S[i] <= 1000000).?? has a magic so that he can change 0 to any interger(He does not need to change all 0 to the same interger).?? wants you to help him to find out the length of the longest increasing (strictly) subsequence he can get.

Input
The first line contains an interger T,denoting the number of the test cases.(T <= 10)
For each case,the first line contains an interger n,which is the length of the array s.
The next line contains n intergers separated by a single space, denote each number in S.

Output
For each test case, output one line containing “Case #x: y”(without quotes), where x is the test case number(starting from 1) and y is the length of the longest increasing subsequence he can get.

Sample Input
2
7
2 0 2 1 2 0 5
6
1 2 3 3 0 0

Sample Output
Case #1: 5
Case #2: 5

Hint
In the first case,you can change the second 0 to 3.So the longest increasing subsequence is 0 1 2 3 5.

Author
FZU

Source
2016 Multi-University Training Contest 4


题意:
给你一个数组,其中的0可以变成任何数,求最长的LIS是多长。


题解:
因为0可以变成任何数,那么所有的0是绝对要用上的(就算强行用上,顶多是使原LIS保持长度,不会出现用0减长度的情况)。所以把所有的0单独拿出来后,看剩下数的LIS,为了求出的LIS保证在原位置加入0后仍然是LIS,我们将原本非0的元素都减去前方0的个数再去求LIS,这样就能保证如果此数在LIS中,那么加入0以后也一定是LIS。
因为数据大小和时限的原因,用一个二分nlogn的LIS即可。


//
//  main.cpp
//  160728-4
//
//  Created by 袁子涵 on 16/7/28.
//  Copyright © 2016年 袁子涵. All rights reserved.
//#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>using namespace std;
const int MAXN=100005;
int t,cas;
long long int n,b[MAXN],out,tmp;
long long int num[MAXN];
long long int Search(long long int num,long long int low,long long int high)
{long long int mid;while(low<=high){mid=(low+high)/2;if(num>=b[mid])  low=mid+1;else   high=mid-1;}return low;
}
long long int DP(long long int n)
{long long int i,len,pos;b[1]=num[1];len=1;for(i=2;i<=n;i++){if(num[i]>b[len]){len=len+1;b[len]=num[i];}else{pos=Search(num[i],1,len);b[pos]=num[i];}}return len;
}
long long int total=0;
bool flag;
int main(int argc, const char * argv[]) {scanf("%d",&t);while (t--) {long long int now=0;total=0;cas++;scanf("%lld",&n);for (long long int i=1; i<=n; i++) {scanf("%lld",&tmp);if (tmp==0)total++;elsenum[++now]=tmp-total;}out=DP(now);if (total==n)out=0;cout << "Case #" << cas << ": " << out+total << endl;}return 0;
}

这篇关于DP-HDU-5773-The All-purpose Zero的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/223757

相关文章

hdu4826(三维DP)

这是一个百度之星的资格赛第四题 题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=500 题意:从左上角的点到右上角的点,每个点只能走一遍,走的方向有三个:向上,向下,向右,求最大值。 咋一看像搜索题,先暴搜,TLE,然后剪枝,还是TLE.然后我就改方法,用DP来做,这题和普通dp相比,多个个向上

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

hdu4865(概率DP)

题意:已知前一天和今天的天气概率,某天的天气概率和叶子的潮湿程度的概率,n天叶子的湿度,求n天最有可能的天气情况。 思路:概率DP,dp[i][j]表示第i天天气为j的概率,状态转移如下:dp[i][j] = max(dp[i][j, dp[i-1][k]*table2[k][j]*table1[j][col] )  代码如下: #include <stdio.h>#include

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

usaco 1.1 Broken Necklace(DP)

直接上代码 接触的第一道dp ps.大概的思路就是 先从左往右用一个数组在每个点记下蓝或黑的个数 再从右到左算一遍 最后取出最大的即可 核心语句在于: 如果 str[i] = 'r'  ,   rl[i]=rl[i-1]+1, bl[i]=0 如果 str[i] = 'b' ,  bl[i]=bl[i-1]+1, rl[i]=0 如果 str[i] = 'w',  bl[i]=b

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :