您的位置:首页 > 编程语言 > Go语言

POJ 1179 Polygon(DP)

2010-08-11 19:17 423 查看
本题一次水过,由此纪念一下。(实际上,我这个年纪做这种题实在很丢人)。
题目链接。大意:给一个多边形,每个顶点有一个值,每个边编号从1到N,边的属性是加或者乘。首先先拆掉一条边,剩下的如下做:选定一条边以及这条边的两个端点(两个数)用新顶点替换(新顶点即:按照这条边的属性(加或乘)算出这两个数的乘积或者和)。到最后剩一个点,也就是一个值。求这些值的最大值输出,并输出此时最先拆掉的是哪条边。
用2个一维数组存放这个多边形,其一存放点,其二存放边(加或者乘)。将这2个数组当作循环队列一样的使用即可穷举去掉的边。需要另外2个数组记录最大值和最小值(因为两个负数相乘为正,所以要记录最小值)。
设maxDp[i][j] (minDp[i][j])为从i到j的多边形的最终值的最大值(最小值),再从1到N枚举多边形长度(j-i),依次算出长度为1到N的子多边形的最终值。由此自底向上就算出此多边形的最终值的最大值。我的代码如下:
1: #include <iostream>


2: #include <algorithm>


3: 


4: using namespace std;


5: const int VERTEX_SIZE = 50;


6: const long MAX_INT = (1<<15);


7: const long MIN_INT = -(1<<15);


8: 


9: int vertex[VERTEX_SIZE];


10: char label[VERTEX_SIZE];


11: long maxDp[VERTEX_SIZE][VERTEX_SIZE];


12: long minDp[VERTEX_SIZE][VERTEX_SIZE];


13: 


14: void init(const int size, const int front)


15: {


16:     for (int i=0; i<VERTEX_SIZE; i++)


17:     {


18:         for (int j=0; j<VERTEX_SIZE; j++)


19:         {


20:             if (j==i)


21:                 minDp[i][j] = maxDp[i][j] = vertex[i];


22:             else


23:             {


24:                 maxDp[i][j] = MIN_INT;


25:                 minDp[i][j] = MAX_INT;


26:             }


27:         }


28:     }


29: }


30: 


31: int getRes(const int size, const int front)


32: {


33:     int end=(front+size)%size;


34:     for (int len=1; len<size; len++)


35:     {


36:         bool flag=true;


37:         for (int i=front; flag || (i+len)%size!=end; i=(i+1)%size)


38:         {


39:             flag = false;


40:             int j=(i+len)%size;


41:             for (int k=i; k!=j; k=(k+1)%size)


42:             {


43:                 if (label[(k+1)%size]=='x')


44:                 {


45:                     maxDp[i][j] = max(maxDp[i][j], maxDp[i][k]*maxDp[(k+1)%size][j]);


46:                     maxDp[i][j] = max(maxDp[i][j], minDp[i][k]*minDp[(k+1)%size][j]);


47: 


48:                     minDp[i][j] = min(minDp[i][j], maxDp[i][k]*maxDp[(k+1)%size][j]);


49:                     minDp[i][j] = min(minDp[i][j], maxDp[i][k]*minDp[(k+1)%size][j]);


50:                     minDp[i][j] = min(minDp[i][j], minDp[i][k]*maxDp[(k+1)%size][j]);


51:                     minDp[i][j] = min(minDp[i][j], minDp[i][k]*minDp[(k+1)%size][j]);


52:                 }


53:                 else if (label[(k+1)%size]=='t')


54:                 {


55:                     maxDp[i][j] = max(maxDp[i][j], maxDp[i][k]+maxDp[(k+1)%size][j]);


56:                     minDp[i][j] = min(minDp[i][j], minDp[i][k]+minDp[(k+1)%size][j]);


57:                 }


58:             }


59:         }


60:     }


61: 


62:     return maxDp[front][(front+size-1)%size];


63: }


64: 


65: int main()


66: {


67:     int size=0;


68:     cin >> size;


69:     for (int i=0; i<size; i++)


70:         cin >> label[i] >> vertex[i];


71:     int recordLabel[VERTEX_SIZE]={0};


72:     int maxNum = MIN_INT;


73:     for (int i=0; i<size; i++)


74:     {


75:         init(size, i);


76:         recordLabel[i] = getRes(size, i);


77:         maxNum = max(maxNum, recordLabel[i]);


78:     }


79:     cout << maxNum << endl;


80:     bool first = true;


81:     for (int i=0; i<size; i++)


82:     {


83:         if (maxNum==recordLabel[i] && first)


84:         {


85:             cout << (i+1);


86:             first = false;


87:             continue;


88:         }


89:         if (maxNum==recordLabel[i] && (!first))


90:         {


91:             cout << ' ' << (i+1);


92:             continue;


93:         }


94:     }


95:     cout << endl;


96: 


97:     return 0;


98: }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: