#include<iostream> using namespace std; #define MAXN 100003 #define INF ((1LL)<<60) long long dp[MAXN]; int f[MAXN]; int b[MAXN]; long long sum[MAXN]; struct SegTree{ int left[MAXN*4],right[MAXN*4]; long long _min[MAXN*4]; inline void build(int l,int r,int k){ left[k]=l; right[k]=r; if(l==r){ _min[k]=INF; return ; } int m=(l+r)>>1; build(l,m,k*2); build(m+1,r,k*2+1); push_up(k); } inline void push_up(int k){ _min[k]=(_min[k*2]<_min[k*2+1]?_min[k*2]:_min[k*2+1]); return ; } inline long long getMin(){ return _min[1]; } inline void insert(int ind,long long val,int k){ if(left[k]==right[k]){ _min[k]=val; return ; } int mid=(left[k]+right[k])>>1; if(ind<=mid) insert(ind,val,k*2); else insert(ind,val,k*2+1); push_up(k); return ; } inline void delet(int ind,int k){ if(left[k]==right[k]){ _min[k]=INF; return ; } int mid=(left[k]+right[k])>>1; if(ind<=mid) delet(ind,k*2); else delet(ind,k*2+1); push_up(k); } }sgt; struct node{ int val,pos; }queue[MAXN]; int front,back; void del(int j){ while(front!=back){ if(queue[front].pos<=j) { if(front+1<back) sgt.delet(queue[front].pos,1); front++; } else break; } } void ins(int i){ int val=f[i]; while(front!=back){ if(queue[back-1].val<=val){ if(front+1<back) sgt.delet(queue[back-2].pos,1); back--; } else break; } queue[back].val=val; queue[back++].pos=i; if(back-front>1) sgt.insert(queue[back-2].pos,dp[queue[back-2].pos]+queue[back-1].val,1); } int binarySearch(long long m,int i){ int low=1,high=i,mid; while(low<=high){ int mid=(low+high)>>1; if(sum[i]-sum[mid-1]<=m) high=mid-1; else low=mid+1; } return high; } void initB(int n,long long m){ int i; for(i=1;i<=n;i++) b[i]=binarySearch(m,i); } void process(int n,long long m){ sgt.build(0,n,1); dp[0]=0; int i,j; front=back=0; int pre; for(i=1;i<=n;i++){ del(b[i]); ins(i); pre=b[i]; dp[i]=dp[pre]+queue[front].val; long long tmp=sgt.getMin(); if(tmp!=INF){ if(tmp<dp[i]) dp[i]=tmp; } } } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int n; long long m; while(scanf("%d%I64d",&n,&m)!=EOF){ // cout<<m<<endl; int i; for(i=1;i<=n;i++) scanf("%d",&f[i]); for(i=1;i<=n;i++) if(f[i]>m) break; if(i<=n){printf("-1/n");continue;} sum[0]=0; for(i=1;i<=n;i++) sum[i]=sum[i-1]+f[i]; initB(n,m); process(n,m); printf("%lld/n",dp[n]); } }
Mayor’s posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 60890 Accepted: 17606 Des
這個題最初是在HDUOJ上看到的,沒費什麼勁,直接水過。POJ也沒費勁。後來發現學校OJ上也有這麼一道題,就直接把昨晚寫完的代碼交上去。非常詭異的TLE了。唉,各種優化,各種糾結,C寫完用C++寫。結局還是TLE。後來想起來這個題要打表。
題目大意:給定一些用字符,連接符,數字組成的號碼,將這些號碼按照規定格式,最終都轉換爲數字格式。輸出重複的號碼和次數。 解題思路:全存爲數字後,快排,若某個號碼出現多於2次則輸出。 // 620k 782ms #include <iost
直接暴力求是否是子串,就是在子串中加入一些字母。LCS的方法以後再想吧。 #include <iostream> #include <cstdio> #include <cstring> using namespace std; in
題目大意:給定一組DNA序列,只包含A,C,G,T,按每個序列的逆序數排序。比如DCBA,逆序數爲3+2+1=6。 解決方法:求每一個DNA序列逆序數,從序列的後面向前遍歷,eg.如果遇到C,就加上之前A和B的數量,同時自身加一,然後根據
題目跟POJ2299差不多,只不過數據集變小了,用冒泡排序也可以。 // 204k 204ms #include <iostream> using namespace std; const int inf = 1000001; in
題目大意:求一個數的逆序數,比如54321的逆序數爲4+3+2+1+0=10,逆序數 = 在只交換相鄰兩數的前提下,需要的交換次數。 解題思路:因爲這題數據量爲50W,時間限制爲7000ms,用冒泡排序找相鄰交換次數肯定超時,因此用歸併排
轉自http://blog.csdn.net/lyy289065406/article/details/6647445 題目大意:給定25W條木棒,木棒兩個端點爲表示顏色的字符串,比如blue, red,能否根據端點顏色相同這個條件,將這
題目大意:跟POJ2002一摸一樣,就數據由1000變爲2000,找正方形形。 解題思路:已知: (x1,y1) (x2,y2) 則: x3=x1+(y1-y2) y3= y1-(x1-x2) x4=x2+(y1-
題目大意:最多有10w個牛,每個牛有最多30個特徵,比如特徵 10,可以表示爲二進制形式1010,現在要求出在一個連續區間,牛的每個特徵數目相等時,連續區間的最大長度。 解題思路:sum[i][j]表示從第1個到第i個牛,特徵j出現的總數
題目鏈接 http://poj.org/problem?id=1065 題目意思非常簡單,有一堆方木需要處理,處理準備時間如下:第一塊方木需要時間爲1;如果當前處理方木的長寬都大於等於前一塊方木,那麼準備時間爲0。 此題w
題目鏈接:http://poj.org/problem?id=1477 典型的貪心算法,很水,直接貼代碼 PS:需要注意的就是每組數據之後都有一個空行 #include <stdio.h> #include <algorithm
題目鏈接:http://poj.org/problem?id=3070 創建如下矩陣求解遞推式Fn項的值: 代碼如下: #include <cstdio> #include <cstring> const int mod = 1
Jungle Roads Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22995 Accepted: 10727 Description T
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 15862 Accepted: 7902 Description Railw