G - Rectangular Polygon
Problem Description
A rectangular polygon is a polygon whose edges are all parallel to the coordinate axes. The polygon must have a single, non-intersecting boundary. No two adjacent sides must be parallel.
Johnny has several sticks of various lengths. He would like to construct a rectangular polygon. He is planning to use sticks as horizontal edges of the polygon, and draw vertical edges with a pen.
Now Johnny wonders, how many sticks he can use. Help him, find the maximal number of sticks that Johnny can use. He will use sticks only as horizontal edges.
Input
Output
. If no polygon can be constructed, output l = 0.
Sample Input
4 1 2 3 5 4 1 2 4 8 4 1 1 1 1
Sample Output
3 0 0 1 0 1 1 3 1 3 2 0 2 0 4 0 0 1 0 1 1 2 1 2 -2 1 -2 1 -1 0 -1
Hint
单组数据
In the first example Johnny uses a stick of length 1 for (0, 0)−(1, 0) edge, a stick of length 2 for (1, 1)−(3, 1) edge and a stick of length 3 for (3, 2) − (0, 2) edge. There is no way to use all four sticks.
题意不是很清楚,就知道是求尽可能多的2堆木杆长度相等,然后搞一搞输出就行了。
dp[i][j]表示第i根木杆时两堆差为j-20000时最多的木杆数,记录路径按题目格式转换输出就行了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <queue>
#include <map>
using namespace std;
const int inf=0x3f3f3f3f;
int dp[105][40005],path[105][40005];
vector<int> vec1,vec2;
int n,a;
int main()
{
scanf("%d",&n);
memset(dp,-inf,sizeof(dp));
int l=20000-n*200;
int r=20000+n*200;
dp[0][20000]=0;
for(int i=1;i<=n;i++){
scanf("%d",&a);
for(int j=l;j<=r;j++){
if(dp[i-1][j]==-inf)continue;
if(dp[i][j+a]<dp[i-1][j]+1){
dp[i][j+a]=dp[i-1][j]+1;
path[i][j+a]=j;
}
if(dp[i][j-a]<dp[i-1][j]+1){
dp[i][j-a]=dp[i-1][j]+1;
path[i][j-a]=j;
}
if(dp[i][j]<dp[i-1][j]){
dp[i][j]=dp[i-1][j];
path[i][j]=j;
}
}
}
printf("%d\n",dp[n][20000]);
int t=20000;
for(int i=n;i>=1;i--){
int tmp=path[i][t];
if(t>tmp) vec1.push_back(t-tmp);
if(t<tmp) vec2.push_back(tmp-t);
t=tmp;
}
int x=0,y=-1;
for(int i=0;i<vec2.size();i++){
printf("%d %d\n",x,++y);
x+=vec2[i];
printf("%d %d\n",x,y);
}
y=0;
for(int i=0;i<vec1.size();i++){
printf("%d %d\n",x,--y);
x-=vec1[i];
printf("%d %d\n",x,y);
}
return 0;
}