zoj 2710 Two Pipelines

來源:互聯網
上載者:User

    這題我是用dp過的,回頭看了網上的資料,可以用談心。再想想吧,先儲存以下代碼:

/* * zoj_2710.cpp */#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>using namespace std;#defineN210#define INF1e12/* * dp[i][x][y]: The state is x:pipeline1 and y:pipeline2, after decising the ith city. */double dp[2][N][N];double cost[N][2];bool decision[N][N][N];int n, c;struct Point {int x, y;};Point pipe0[2], pipe1[2];Point city[N];int demand[N];inline double cross_dis( int x0, int y0, int x, int y ){return fabs( double( x0*y-x*y0 ) )/sqrt( double(x0*x0+y0*y0) );}inline double func_cost( int idx, int which ) {Point pt0, pt1, pt;double d;if ( 0 == which ) {pt0 = pipe0[0];pt1 = pipe0[1];}else if ( 1 == which ) {pt0 = pipe1[0];pt1 = pipe1[1];}pt = city[idx];/*if ( point_multi( pt0, pt1, pt ) == false ) { //<0d = distance( &pt0, &pt );}else if ( point_multi( pt1, pt0, pt ) == false ) { //<0d = distance( &pt1, &pt );}*/d = cross_dis( pt1.x-pt0.x, pt1.y-pt0.y, pt.x-pt0.x, pt.y-pt0.y );return ( d * demand[idx] );}void print_ans( int i, int x ) {//x: pipeline1 countif ( i < 1 )return;if ( decision[i][x][i-x] ) {print_ans( i-1, x );printf("2 ");}else {print_ans( i-1, x-1 );printf("1 ");}}int main(){int i, k, x, y, a;double tmp0, tmp1, min;while ( scanf("%d%d", &n, &c ) != EOF ) {scanf("%d%d%d%d", &pipe0[0].x, &pipe0[0].y, &pipe0[1].x, &pipe0[1].y );scanf("%d%d%d%d", &pipe1[0].x, &pipe1[0].y, &pipe1[1].x, &pipe1[1].y );for ( i = 1; i <= n; ++ i ) {scanf("%d%d%d", &city[i].x, &city[i].y, &demand[i] ); }memset( dp[0], 0, sizeof(dp[0]) );a = 0;for ( i = 1; i <= n; ++ i ) {cost[i][0] = func_cost( i, 0 );cost[i][1] = func_cost( i, 1 );dp[1-a][0][i] = dp[a][0][i-1] + cost[i][1];decision[i][0][i] = true;dp[1-a][i][0] = dp[a][i-1][0] + cost[i][0];decision[i][i][0] = false;for ( x = 1; x < i; ++ x ) {y = i - x;tmp0 = dp[a][x-1][y] + cost[i][0];tmp1 = dp[a][x][y-1] + cost[i][1];if ( tmp1 > tmp0 ) {dp[1-a][x][y] = tmp0;decision[i][x][y] = false;}else {dp[1-a][x][y] = tmp1;decision[i][x][y] = true;}}a = 1 - a;}min = INF;for ( x = 0; x <= n; ++ x ) {y = n-x;if ( abs(x-y) <= c && dp[a][x][y] <= min ) {min = dp[a][x][y];k = x;}}if ( decision[n][k][n-k] ) {//pipeline1print_ans( n-1, k );printf("2\n");}else {print_ans( n-1, k-1 );printf("1\n");}}return 0;}

    回宿舍又想了一下,使用貪心,代碼

/* * zoj_2710_2.cpp * greedy codes */#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>#include <cmath>#include <algorithm>using namespace std;#define N 210#define eps1e-9struct Node {double dis;unsigned char decision;short idx;};Node node[N];struct Point {int x, y;};Point pipe0[2], pipe1[2];short ans[N];int n, c;inline double cross_dis( int x0, int y0, int x, int y ){return fabs( double( x0*y-x*y0 ) )/sqrt( double(x0*x0+y0*y0) );}inline double dis( int x, int y, int which ) {Point pt0, pt1;double d;if ( 0 == which ) {pt0 = pipe0[0];pt1 = pipe0[1];}else if ( 1 == which ) {pt0 = pipe1[0];pt1 = pipe1[1];}d = cross_dis( pt1.x-pt0.x, pt1.y-pt0.y, x-pt0.x, y-pt0.y );return ( d );}int cmp( Node const& a, Node const& b ){return ( a.dis+eps < b.dis );}int main(){int i, x, y, k, demand, tmp;double tmp0, tmp1;while ( scanf("%d%d", &n, &c ) != EOF ) {scanf("%d%d%d%d", &pipe0[0].x, &pipe0[0].y, &pipe0[1].x, &pipe0[1].y );scanf("%d%d%d%d", &pipe1[0].x, &pipe1[0].y, &pipe1[1].x, &pipe1[1].y );for ( i = 1; i <= n; ++ i ) {scanf("%d%d%d", &x, &y, &demand ); tmp0 = dis(x,y,0);tmp1 = dis(x,y,1);if ( tmp0 > tmp1 ) {node[i].decision = 1;}else{  node[i].decision = 0;}node[i].dis = fabs( tmp0-tmp1 ) * demand; node[i].idx = i;}sort( node+1, node+n+1, cmp );x = y = 0;for ( i = 1; i <= n; ++ i ) {if ( 0 == node[i].decision )++ x;else++ y;}if ( abs(x-y) > c ) {if ( x > y )tmp = 0;elsetmp = 1;k = (abs(x-y)-c+1)/2;for ( i = 1; i <= n; ++ i ) {if ( node[i].decision == tmp ) {node[i].decision = 1-tmp;-- k;}//注意這裡,不能單純的把前k個decision反轉。這裡卡了一下。if ( 0 == k )break;}}for ( i = 1; i <= n; ++ i )ans[ node[i].idx ] = node[i].decision+1;for ( i = 1; i < n; ++ i )printf("%d ", ans[i] );printf("%d\n", ans[i] );}return 0;}

如下:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.