關於連續子序列的題的總結:(dp)
阿新 • • 發佈:2018-12-22
第一道題:hdu 1003 Max Sum
這到就是簡單的dp題目:狀態轉移方程 dp[j] = max(dp[j-1] + a[j], a[j]);然後通過一個值來記錄最值集合位置:
記錄位置可以定義幾個變數來記錄:st, en, x,y;並且根據情況不斷更新;
程式碼如下:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<set> #include<map> #include<queue> #define pi acos(-1) #define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++) #define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --) #define max(a,b) (((a)>(b))?(a):(b)) #define min(a,b) (((a)<(b))?(a):(b)) #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 #define eps 1e-7 using namespace std; typedef long long ll; const int maxn = 1e5 + 10; const int INF = 0x3f3f3f3f; const double EPS = 1e-10; const ll mod = 1e9 + 7; ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;} inline int read(){ int ret=0,f=0;char ch=getchar(); while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar(); while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar(); return f?-ret:ret; } int t; int a[maxn]; int dp[maxn]; int main(){ ios::sync_with_stdio(false); cin >> t; int n; int kase = 0; int p = t; while(t--){ cin >> n; kase ++; memset(dp,0,sizeof(dp)); for(int i = 1; i <= n; i++)cin >> a[i]; int end = 1, start = 1, x = 1, y = 1;//對位置進行初始化 int maxnn = -1001; for(int i = 1; i <= n; i++){ if(dp[i-1]+a[i] < a[i]){ x = i; y = i;//更新位置和最值; dp[i] = a[i]; }else{ dp[i] = dp[i-1] + a[i]; y = i; } if(maxnn < dp[i]){//記錄最大值和開始和結束的位置,並且這是記錄的最早到達最大值的位置; start = x; end = y; maxnn = dp[i]; } } cout << "Case " << kase << ":" << endl; cout << maxnn << " " << start << " " << end << endl; if(kase != p) cout << endl; } return 0; }
hdu 1231 最大連續子序列
這個就是和1003差不多知識他求的是最值的兩邊的值;
程式碼很相似:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<set> #include<map> #include<queue> #define pi acos(-1) #define e exp(1) #define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++) #define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --) #define max(a,b) (((a)>(b))?(a):(b)) #define min(a,b) (((a)<(b))?(a):(b)) #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 #define eps 1e-7 #define INF 0x3f3f3f3f #define inf -2100000000 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxn = 10000 + 10; const double EPS = 1e-10; const ll p = 1e7+9; const ll mod = 1e9+7; ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;} inline int read(){ int ret=0,f=0;char ch=getchar(); while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar(); while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar(); return f?-ret:ret; } int n; int a[maxn]; int dp[maxn]; int main(){ ios::sync_with_stdio(false); while(cin >> n && n){ for(int i = 1; i <= n; i++){ cin >> a[i]; } int st=1, en=1, x=1, y=1; memset(dp, 0, sizeof(dp)); int cnt = inf; for(int i = 1; i <= n; i++){ if(dp[i-1] + a[i] < a[i]){ st = i; en = i; dp[i] = a[i]; }else{ en = i; dp[i] += dp[i-1] + a[i]; } if(dp[i] > cnt){ cnt = dp[i]; x = st; y = en; } } if(cnt < 0){ cout << 0 << " " << a[1] << " " << a[n] << endl; }else{ cout << cnt << " " << a[x] << " " << a[y] << endl; } } return 0; }
hdu 1024 Max Sum Plus Plus
這個題你上面兩道都難,他的的狀態轉移方程不是很好寫,有一個部落格寫的很好
https://www.cnblogs.com/kuangbin/archive/2011/08/04/2127085.html
程式碼入下:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<set> #include<map> #include<queue> #define INF 0x3f3f3f3f #define inf -2100000000 #define pi acos(-1) #define e exp(1) #define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++) #define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --) #define max(a,b) (((a)>(b))?(a):(b)) #define min(a,b) (((a)<(b))?(a):(b)) #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 #define eps 1e-7 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxn = 1e6 + 10; const double EPS = 1e-10; const ll p = 1e7+9; const ll mod = 1e9+7; ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;} inline int read(){ int ret=0,f=0;char ch=getchar(); while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar(); while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar(); return f?-ret:ret; } int n, m; int dp[maxn], f[maxn]; int a[maxn]; int main(){ ios::sync_with_stdio(false); while(cin >> m >> n){ for(int i = 1; i <= n; i++){ cin >> a[i]; } memset(f, 0, sizeof(f)); memset(dp, 0, sizeof(dp)); int maxnn; for(int i = 1; i <= m; i ++){ maxnn = inf; for(int j = i; j <= n; j++){ dp[j] = max(dp[j-1], f[j-1])+a[j]; f[j-1] = maxnn; maxnn = max(maxnn, dp[j]); } } cout << maxnn << endl; } return 0; }