2016集训小记

来源:互联网 发布:自媒体是什么 知乎 编辑:程序博客网 时间:2024/06/05 00:22
Deliver Pizzashttp://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=4202dp预处理参考标程
#include <cstring>#include <cstdio>#define maxr 2000#define maxs 200#define inf -1int r, s, grid[maxr][maxs], sum[maxr][maxs]; // parcijalne sume za svaki redak// G[i][j][k] = tezina brida od (j==0? lijevog: desnog) polja i-tog retka, u smjeru k (vodoravno,gore,dolje)// dp[i][a][j][b] = najkraci put od i-tog retka do j-tog retka, s kojeg kraja retka odredjuju a i bint G[maxr][2][3], dp[maxr][2][maxr][2];void initsum() { // parcijalne sumefor( int i = 0; i < r; ++i ) {sum[i][0] = grid[i][0];for( int j = 1; j < s; ++j ) sum[i][j] = sum[i][j-1] + grid[i][j];}}int fsum( int i, int l, int r ) { // suma u i-tom retku u intervalu [l,r>if( r == 0 ) return 0;if( l == 0 ) return sum[i][r-1];return sum[i][r-1] - sum[i][l-1];}void load() {scanf( "%d%d", &r, &s );for( int i = 0; i < r; ++i )for( int j = 0; j < s; ++j ) scanf( "%d", &grid[i][j] );}void initg() { // nagradi graffor( int i = 0; i < r; ++i ) {if( i == 0 ) G[i][0][0] = G[i][1][0] = inf;else { G[i][0][0] = grid[i-1][0]; G[i][1][0] = grid[i-1][s-1]; }if( i+1 == r ) G[i][0][2] = G[i][1][2] = inf;else { G[i][0][2] = grid[i+1][0]; G[i][1][2] = grid[i+1][s-1]; }G[i][0][1] = fsum( i, 1, s );G[i][1][1] = fsum( i, 0, s-1 );}}int manji( int a, int b ) {if( a == inf ) return b;if( b == inf ) return a;return a<b? a: b;}void initdp() { // dinamicki popuni tablicumemset( dp, inf, sizeof dp );for( int k = 0; k < 2; ++k ) {for( int i = 0; i < r; ++i ) {dp[i][k][i][k] = 0;int ll = 0, rr = 0;for( int j = i;; ++j) {dp[i][k][i][1-k] = manji( dp[i][k][i][1-k], ll+rr+G[j][k][1] );if( j+1 == r ) break;ll += G[j][k][2];rr += G[j+1][1-k][0];}ll = rr = 0;for( int j = i;; --j) {dp[i][k][i][1-k] = manji( dp[i][k][i][1-k], ll+rr+G[j][k][1] );if( j-1 < 0 ) break;ll += G[j][k][0];rr += G[j-1][1-k][2];}}}for( int t = 1; t < r; ++t ) {for( int i = 0; i < r-t; ++i ) {for( int k = 0; k < 2; ++k ) {dp[i][k][i+t][k] = manji( dp[i][k][i+t][k], dp[i+1][k][i+t][k] + G[i][k][2] );dp[i][k][i+t][k] = manji( dp[i][k][i+t][k], dp[i][k][i][1-k] + G[i][1-k][2] + dp[i+1][1-k][i+t][k] );dp[i][k][i+t][1-k] = manji( dp[i][k][i+t][1-k], G[i][k][2] + dp[i+1][k][i+t][1-k] );dp[i][k][i+t][1-k] = manji( dp[i][k][i+t][1-k], dp[i][k][i][1-k] + G[i][1-k][2] + dp[i+1][1-k][i+t][1-k] );}}for( int i = t; i < r; ++i ) {for( int k = 0; k < 2; ++k ) {dp[i][k][i-t][k] = manji( dp[i][k][i-t][k], dp[i-1][k][i-t][k] + G[i][k][0] );dp[i][k][i-t][k] = manji( dp[i][k][i-t][k], dp[i][k][i][1-k] + G[i][1-k][0] + dp[i-1][1-k][i-t][k] );dp[i][k][i-t][1-k] = manji( dp[i][k][i-t][1-k], G[i][k][0] + dp[i-1][k][i-t][1-k] );dp[i][k][i-t][1-k] = manji( dp[i][k][i-t][1-k], dp[i][k][i][1-k] + G[i][1-k][0] + dp[i-1][1-k][i-t][1-k] );}}}}// udaljenost od tocke do tocke, od cetiri moguca nacina putovanja odaberemo najboljiint dist( int r1, int s1, int r2, int s2 ) {int d1 = fsum( r1, 0, s1 ) + dp[r1][0][r2][0] + fsum( r2, 1, s2+1 );int d2 = fsum( r1, 0, s1 ) + dp[r1][0][r2][1] + fsum( r2, s2, s-1 );int d3 = fsum( r1, s1+1, s ) + dp[r1][1][r2][0] + fsum( r2, 1, s2+1 );int d4 = fsum( r1, s1+1, s ) + dp[r1][1][r2][1] + fsum( r2, s2, s-1 );int ret = manji( manji( d1, d2 ), manji( d3, d4 ) );if( r1 == r2 ) {if( s1 < s2 ) ret = manji( ret, fsum( r1, s1+1, s2+1 ) );else ret = manji( ret, fsum( r1, s2, s1 ) );}return ret;}void solve() {long long sol = grid[0][0];int m, a, b, cr = 0, cs = 0;for( scanf( "%d", &m ); m; --m ) {scanf( "%d%d", &a, &b );sol += dist( cr, cs, a-1, b-1 );cr = a-1;cs = b-1;}printf( "%I64d\n", sol );}int main(void) {load();initsum();initg();initdp();solve();return 0;}
FUNKCIJAhttp://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=4484神DP,并不会Karel the Robothttp://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=4991我的思路是并查集加广搜Palindromic Pathshttp://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=5020首先最简单的,dp[i][j][k][t]代表从左上角走到点i,j和从右下角走到k,t回文串的个数,空间过不去,发现2个点走的步数是一样的,而且行数和列数是一样的,根据步数和所在的行数可以推出所在的列数,dp数组改成dp[k][i][j],k表示走了k步,2个点分别位于第i行和第j行,滚动一下。。Exchange Puzzlehttp://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=5021只要求7的倍数,所以把所有的输入都模7,记录每种余数的个数,最后暴力for循环,乘法原理计数即可。Fence按照刷或者不刷dp并且记录个数即可,用单调队列维护最小值。Tunnels并查集?按照prim的思想,每次找已经合并的集合里面出去最小权值的边,在这里是3维独立的差的绝对值,所以可以维护3个有序的数据结构,代表3维,与一个点最近的点可以找当前点的左边或者右边那个点,3维找出之后取最小值,然后删掉,不知道是不是正解。
0 0
原创粉丝点击