這周刷題主要是以線性dp為主,按照慣例,先陳述一下這週的感受。
接觸dp有一段時間了,很難的乙個專題,能看題解看明白,但自己怎麼著都想不過來。應該是從上週日開始,連續兩天碰到了許多求最大欄位和的問題,也從中學到了許多,下面會主要介紹一下介紹一下。
不過這周雖然主要進行的dp的刷題,但搜尋卻出現的頻率挺高,無論是在dp中還是資訊學奧賽上的佇列練習。
以下題目分類主要是:
關於欄位和的dp問題
關於搜尋的dp問題
這個題是求最小字段和,和最大欄位和類似,是dp裡最基本的題型,只需要列舉間斷點i,求出i到j(j<=n)的字段和就可以#include #include #include #include #include #include #include #define sf(a) scanf("%d\n",&a)
#define pf(a) printf("%.2lf\n",a)
#define pi acos(-1.0)
#define e 1e-8
#define ms(a) memset(a,0,sizeof a)
#define mst(a) memest(a,0x3f3f3f3f,sizeof a)
#define rep(a,b,c) for(int a=b;a<=c;a++)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int idata=1e6+5;
int i,j,k;
int judge,flag;
int n,m,t,ans;
int maxx=0,minn=inf;
int cnt,len,sum;
//int dp[idata][idata];
priority_queue,less>q;
int step[idata];
int dp[idata];
int main()
}cout<<"case "《經過上面 題目後,接著高階一下就是最大二子段和問題:這個題老師上課講過,在練習中只能用o(n)的解法ac,其他的都超時了,時間卡的太緊了(因為這個wrong了無數次)
我的思路:一開始做這個題的時候,也是看著挺簡單的,要求最大二子段和只需要列舉第i個點,第i個點左邊的和加第i個點右邊的和的最大值所以dp狀態很容易表示為到i位置的最大欄位和,當然需要從左邊遍歷,和從右邊遍歷。但要怎麼求到i位置的最大欄位和呢???
以從左邊求為例:
最大欄位和肯定不允許是負數或者較大的負數,因為這只能使他最小
所以先求出dp[i]=max(dp[i-1]+a[i],a[i])(dp[i]表示到a[i]為結尾的最大欄位和)
然後求出l[i]=max(dp[i-1]+a[i],dp[i])(l[i]表示到a[i]位置的最大欄位和,不一定包含a[i])
大家看下面的**
temp[i]=max(temp[i-1]+step[i],step[i]);
dp[i][0]=max(dp[i-1][0],temp[i]);
但是很遺憾tle不要太過分,最後翻了翻老師上課講的課件,私以為調動max函式次數過多而導致超時
但課上講的方法空間複雜度也減少許多
依舊以左邊為例:
dp[i]=max(dp[i-1],sum+a[i]),這樣只需要保證sum是到目前為止的最大字段(dp[i]表示到a[i]位置的最大欄位和,不一定包含a[i])
當然sum必須有歸0的過程,才能列舉各間斷點到a[i]的和
這樣無論包含a[i]還是不包含的情況都列舉了
dp[0][0]=-inf;
sum=0;
for(i=1;i<=n;i++)
printf("%d\n",maxx);
關於欄位和 問題就介紹到這裡
這是乙個簡單的生存遊戲,你控制乙個機械人從乙個棋盤的起始點(1,1)走到棋盤的終點(n,m)。遊戲的規則描述如下:
1.機械人一開始在棋盤的起始點並有起始點所標有的能量。
2.機械人只能向右或者向下走,並且每走一步消耗一單位能量。
3.機械人不能在原地停留。
4.當機械人選擇了一條可行路徑後,當他走到這條路徑的終點時,他將只有終點所標記的能量。
機械人一開始在(1,1)點
根據題目要求:dp[i][j]表示從i,j點到n,m點的方式數(方程有點難想)
只要用當前資源可以走,就可以進行dfs遞迴求解即可
完整**:
#include #include #include #include #include #include #include #include #include #include #include #define sf(a) scanf("%d\n",&a)
#define pf(a) printf("%.2lf\n",a)
#define pi acos(-1.0)
#define e 1e-8
#define ms(a) memset(a,-1,sizeof a)
#define rep(a,b,c) for(int a=b;a<=c;a++)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int idata=100+5;
const int mod=1e4;
//int i,j,k;
int judge,flag;
int p[idata][idata];
int dp[idata][idata];
int n,m,t;
ll maxx=0,minn=inf;
ll cnt,len,sum,ans;
//mappre[2];
string s;
priority_queue,less>q;
int dfs(int x,int y)}}
return dp[x][y];
}int main()
ms(dp);
cout《題目就講這麼多,最後在總結一下:
acm的課上了也挺久了,所收穫嗎,也有,但仔細想想能想出來的很少。從這週開始0點睡覺已經成為幻想,cf的比賽開的太晚了,刷dp的問題的時候有時候因為方程的錯誤而重新打**也是常有的事。
在這週ac的愉悅感也感受到那麼幾次,不過關於學習演算法的目的還是沒有變,初次意識到降低時間複雜度和空間複雜度很重要,真的很重要(強調一下),有的時候tle真的制得我沒毛病。
這次訓練總結就寫這麼多,cf補題去了
第六周訓練總結
前四天看了一下國慶 的題目,只出了e題。這個題目要求求區間最值,區間最值其實和區間求和差不多,就是將sum陣列的含義轉移到 max,然後通過特定的區間更新 max。在區間求和中,當我們維護max i 的時候,要找到它前面所有的 max j 來更新,畫圖可知,max i 需要的max 只有max i ...
第六周總結
2 關於register 提高速度 儲存型別說明符 register要求變數儲存在cpu暫存器中,所以不能用取位址符 取其位址,並且,在全域性變數的地方不能出現register 防止儲存型別不唯一引起的衝突。同時,register 變數必須是能被cpu暫存器所接受的型別。這就意味著,register...
總結第六周
這一周從時間意義上也算是國慶假期後的第一周,學弟學妹也正式踏入了校園,我們工作室的招新工作也相繼展開,截止到此時此刻,還有資料專業和物聯專業的學弟學妹沒有來到我們工作室進行參觀,這兩天也挺累的,但也從中收穫到了許多東西,比如 在人多的時候講話可以更淡定一點,沒有那麼緊張 跟學弟學妹交流用怎樣的方式更...