矩陣中求左上角的點到右下角的點的距離,不能從下往上走
方案1(動規)
初步判定演算法
對於這題,只能從上往下行走,對於到達每乙個點的最優值,一定是從最上方下來的最優值,與左右兩邊最優值的比較,初步確定演算法動態規劃
分析初步演算法
對於從兩邊來的最優值,只有左邊目前是一路dp過來的最優值,而對於右邊則是乙個未知的,所以要進行兩步dp,想從左邊掃一遍左值,在從右掃一遍右值,上方,左右三者取乙個min則是到這個點的最小花
方案2(最短路)
初步判定演算法
典型的最短路問題
分析初步演算法
將每乙個節點,按照從上到下,從左到右的順序編號,點數為n*m
建立到右邊乙個點,權值為右邊那個點的權值的邊,再建立到左邊乙個點,權值為左邊那個點的權值的邊,再建立到下邊乙個點,權值為下邊那個點的權值的邊。邊數為3*m*n
跑乙個最短路dijkstra,時間複雜度o(n*log(m)),對於這道題時間上是跑不過去的,可以得部分分
#include#include#include
#define inf 2147483647
#define fora(i,s,e) for(int i=s;i<=e;i++)
#define fors(i,s,e) for(int i=s;i>=e;i--)
#define gc pa==pb&&(pb=(pa=buf)+fread(buf,1,100000,stdin),pa==pb)?eof:*pa++
#define file(name) freopen(name".in","r",stdin),freopen(name".out","w",stdout);
using
namespace
std;
static
char buf[1000000],*pa=buf,*pb=buf;
inline
intread();
const
int m=1000,n=1000
;struct
nodeedge[m*n*4
];bool bz[m*n];
int a[n+1][m+1
]; int n,m,star,end,dis[m*n],head[m*n],num_edge,fdis[n+1][m+1
];inline
int min(int fa,int fb)
void add_edge(int
from,int to,int
d),head[from]=num_edge;
}struct
que
}q;priority_queue
que;
void
solve()
);
while(!que.empty()));}
}}printf("%d
",dis[m*n]);
}void
solve2()
fors(j,m,1)
}printf("%d
",fdis[n][m]);
}int
main()
inline
intread()
校內測試 祖先(DP)
首先這個題顯然是應該考慮字元合併,一開始看到這個題的時候想到了某個名字就叫做 字元合併 的撞鴨dp題目。但是那個題和這個題還是有很多不同的地方的,首先這個題可能合併到最後串長仍然很大所以肯定不能撞鴨,並且合併過的字元可能還可以繼續合併,所以好像有點gg。然而這個題可以用某種叫做 看資料範圍猜做法 l...
8 28校內測試 區間DP
感受到了生活的艱辛qaq.這才是真正的爆錘啊.因為t1t3還沒有理解所以只能貼t2叻qaq 區間dp.爆哭把題理解錯了,以為隨著拿的東西越來越多,斷點也會越來越多,出現可以選很多的情況qaq,然而是不會的,自始至終只會有乙個斷點,哥哥和妹妹取都只有兩個方向,而妹妹還是強制選擇的qaq。所以把環展開就...
8 15校內測試 佇列 manacher
dp?不能確定轉移狀態。考慮用優先佇列儲存最優決策點,可是發現當前選擇最優不能保證最後最優,在後面可以將之前用過的替換過來。比如資料 3 54 6 只儲存a i 來決策不能延展到後面的狀態,因此每次選擇過後把b i 加入佇列,下次選擇最優時如果選擇到了b i 則表示用之前選擇過的來替換到當前狀態。這...