Learning Vector UVA

来源:互联网 发布:焱凰赤城 知乎 编辑:程序博客网 时间:2024/05/21 21:39

一道动态规划的题目,首先存入每个向量的信息,注意题目中给出的是向量,而不是顶点。存入信息的同时要计算如果该向量的起点是放置在原点的位置,那么该向量与x轴所围成的面积的两倍,同时在录入完所有的向量信息之后,要将所有的向量按照斜率从大到小进行排序,也就是说,我们尽量先绘制斜率大的向量,这样能够保证后面所绘制的向量与x轴围成的面积也尽量大。同时要计算出所有的向量的y值之和也就是最大的高度。dp[i][j]表示当前已经选取了i个向量并且最终的高度为j时所围成的最大的面积。依次从第一个向量向后选取,同时假设当前需要选取的向量的个数为k,总的高度从最大高度向选取向量的高度递减,判断dp[k-1][j-point[i].y]是否存在,如果存在就进行尝试更新(添加相应的向量,同时判断加入向量之后和之前的k-1个向量围成的面积是否比dp[k][j]要大,如果更大就进行更新)。具体实现见如下代码:

#include<iostream>#include<vector>#include<string>#include<set>#include<stack>#include<queue>#include<map>#include<algorithm>#include<cmath>#include<iomanip>#include<cstring>#include<sstream>#include<cstdio>#include<deque>using namespace std;class node{public:int x, y;int area;};bool compare(const node& a, const  node& b){return a.y*b.x > b.y*a.x;}class Solve{public:int N, K, H;node point[55];int dp[55][2510];void Init(){H = 0;for (int i = 1; i <= N; i++){cin >> point[i].x >> point[i].y;H += point[i].y;point[i].area = point[i].x*point[i].y;}sort(point+1,point+N+1,compare);}void Deal(){Init();memset(dp, -1, sizeof(dp));dp[0][0] = 0;for (int i = 1; i <= N; i++){for (int k = K; k >= 1; k--){for (int j = H; j >= point[i].y; j--){if (dp[k - 1][j - point[i].y] != -1){dp[k][j] = max(dp[k][j], dp[k - 1][j - point[i].y] + 2 * (j - point[i].y)*point[i].x + point[i].area);}}}}int ans = -1;for (int i = 1; i <= H; i++)ans = max(ans,dp[K][i]);cout << ans << endl;}};int main(){int T;cin >> T;Solve a;int Case = 1;while (T--){cin >> a.N >> a.K;cout << "Case " << Case++ << ": ";a.Deal();}return 0;}

原创粉丝点击