2015 百度之星 1005 序列变换 动态规划
序列变换
Time Limit: 20 Sec Memory Limit: 256 MB
题目连接
http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=601&pid=1003
Description
Input
第一行输入一个T(1≤T≤10),表示有多少组数据
每一组数据:
第一行输入一个N(1≤N≤105),表示数列的长度
第二行输入N个数A1,A2,...,An。
每一个数列中的元素都是正整数而且不超过106。
每一组数据:
第一行输入一个N(1≤N≤105),表示数列的长度
第二行输入N个数A1,A2,...,An。
每一个数列中的元素都是正整数而且不超过106。
Output
Sample Input
2 2 1 10 3 2 5 4
Sample Output
Case #1: 0 Case #2: 1
HINT
题意
题解:
先减去下标,然后求最长上升子序列,这是道原题,见到很多次了= =
答案就是n-最长上升子序列长度
代码:
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; const int MAXN=100010; int a[MAXN],b[MAXN]; //用二分查找的方法找到一个位置,使得num>b[i-1] 并且num<b[i],并用num代替b[i] int Search(int num,int low,int high) { int mid; while(low<=high) { mid=(low+high)/2; if(num>=b[mid]) low=mid+1; else high=mid-1; } return low; } int DP(int n) { int i,len,pos; b[1]=a[1]; len=1; for(i=2;i<=n;i++) { if(a[i]>=b[len])//如果a[i]比b[]数组中最大还大直接插入到后面即可 { len=len+1; b[len]=a[i]; } else//用二分的方法在b[]数组中找出第一个比a[i]大的位置并且让a[i]替代这个位置 { pos=Search(a[i],1,len); b[pos]=a[i]; } } return len; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T ; int iCase = 0; scanf("%d",&T); while(T--){ iCase++; int n; scanf("%d",&n); for(int i = 1;i <= n;i++){ scanf("%d",&a[i]); a[i] -= i; } printf("Case #%d:\n",iCase); printf("%d\n",n - DP(n)); } return 0; }