題目大意:給定乙個序列長度為n,從中去掉長度為l的連續的序列,求剩餘序列中的lis,去掉的序列起始位置隨意
思路:lis變形,只要列舉去掉的所有區間就可以了,最大長度等於以區間右邊第乙個元素開始的lis+區間左邊的小於右邊第乙個元素的lis-1.右邊的直接逆序求lis即可。
左邊的常規lis。左邊的需要計算arr[i+l]在a[1……i]中的最大lis就是我說的那個加法的後半部分。
ps:逆序求lis有兩種方法,第一種是將arr陣列的所有元素取反,然後求。另外一種就是直接開始求,用upper_bound。本來前一天就該過得,但是初始化時的inf開小了,為99999999 ,tmp陣列初始化也小了為0,正確的應該是999999999 , -999999999.
**1:
#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
#define maxn 500005
#define mod 1000000007
#define mem(a , b) memset(a , b , sizeof(a))
#define ll long long
#define *** 1000000005
#define inf 999999999
int arr[maxn];
int b[maxn];
int dp[maxn] ;
int g[maxn];
int main()
mem(dp , 0);
for(int i = 0 ; i <= n ; i ++) g[i] = inf;
// mem(g , 0x7f);
for(int i = n ; i > l ; i --) //逆序lis
// mem(g , 0x7f);
for(int i = 0 ; i <= n ; i ++) g[i] = inf;
int ans = 0 , maxlen = 0 ;
for(int i = 1 ; i <= n - l ; i ++)
ans = max(ans , maxlen); //區間是最後的一段,上面個的**不能比較,需要單獨比較
printf("case #%d: %d\n" , ncase++ , ans);
}return 0;
}
**2:
#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
#define maxn 500005
#define mod 1000000007
#define mem(a , b) memset(a , b , sizeof(a))
#define ll long long
#define *** 1000000005
#define inf 999999999
int dp[maxn];
int dp2[maxn];
int g[maxn];
int tmp[maxn];
int arr[maxn];
int per[maxn];
int main()
for(int i = 0 ; i <= n ; i ++) g[i] = inf ,tmp[i] = -inf;
mem(dp,0);
mem(dp2,0);
mem(per , 0);
int ans = 0;
int len = 0;
for(int i = 1 ; i <= n - l; i ++)
int k = lower_bound(g +1, g + n +1, arr[i]) - g;
dp[i] = k;
g[k] = arr[i];
len = max(len , k);
}ans = max(per[n] , len);
for(int i = n; i > l ; i --) //求逆序lis
for(int i = l + 1 ; i <= n ; i ++)
ans = max(ans , dp[n-l]);
printf("case #%d: %d\n" , ncase++ , ans);
}return 0;
}
hdu5489 樹狀陣列 dp
2015 10 06 21 49 54 這題說的是個給了乙個陣列,然後刪除任意起點的乙個連續的l個數,然後求最長遞增子串行 是遞增,不是非遞減 用乙個樹狀陣列維護一下就ok了 include include include include include using namespace std co...
poj3616(LIS簡單變式)
思路 我的第一反應是揹包,因為每個interval要麼選擇要麼不選,後來發現狀態方程很難寫出來。後來想一想發現就是lis的簡單變式。先按照starting hours給資料排序,那麼選擇的順序也就是排序後的順序,用dp i 表示以第i個interval結尾能獲得最多的milk,狀態轉移方程就是dp ...
HDU1800(貪心,lis變形)
題意 給你n個數,求這些數經過排序後能組成幾組嚴格上公升子串行。解題思路 一開始直接排序模擬,時間複雜度o n n 接著發現其實就是找序列中重複最多的元素。為什麼呢?你想,我們序列排完後假如都不重複就所有人共用1個掃把 如果某段有個元素重複,我們把它提出來,單獨一組,假如有多個重複,並且重複的元素都...