zoj 3905 (dp + 스크롤 그룹)
4405 단어 dp스크롤 배열2015zoj 월간 경기
Time Limit: 4 Seconds
Memory Limit: 65536 KB
Alice and Bob like eating cake very much. One day, Alice and Bob went to a bakery and bought many cakes.
Now we know that they have bought n cakes in the bakery. Both of them like delicious cakes, but they evaluate the cakes as different values. So they decided to divide those cakes by following method.
Alice and Bob do n /2 steps, at each step, Alice choose 2 cakes, and Bob takes the cake that he evaluates it greater, and Alice take the rest cake.
Now Alice want to know the maximum sum of the value that she can get.
Input
The first line is an integer T which is the number of test cases.
For each test case, the first line is an integer n (1<=n<=800). Note that n is always an even integer.
In following n lines, each line contains two integers a[i] and b[i], where a[i] is the value of ith cake that Alice evaluates, and b[i] is the value of ith cake that Bob evaluates. (1<=a[i], b[i]<=1000000)
Note that a[1], a[2]..., a[n] are n distinct integers and b[1], b[2]..., b[n] are n distinct integers.
Output
For each test case, you need to output the maximum sum of the value that Alice can get in a line.
Sample Input
1
6
1 6
7 10
6 11
12 18
15 5
2 14
Sample Output
28
Author:
HUA, Yiwei
Source:
ZOJ Monthly, October 2015
월례 시합 때 또 하지 못해서 정말 속상하다.
제목:
n(n은 짝수) 케이크는 A와 B에게 똑같이 나누어져야 한다. A와 B는 모든 케이크에 대해 그들 자신의 마음속의 가치가 있다.그 다음에 이렇게 똑같이 나눈다. A는 그 중에서 2개를 골라서 B에게 선택하게 한다. B는 그가 가치가 더 높다고 생각하는 부분을 선택하고 다른 하나는 A에게 주고 상술한 조작을 반복해서 나누어질 때까지 한다.A가 얻을 수 있는 최대의 가치를 구하다.
분석:
사실 상태를 잘 정의할 수만 있다면 추이 방정식은 추론하기 어렵지 않다.상태를 정의할 때 방해도 배제해야 한다. 예를 들어 나는 처음에 항상 짝을 지어야 한다고 생각했다.
dp[i][j]는 전 i개의 케이크 중 A가 j개를 선택하여 얻은 가장 큰 합을 나타낸다. 방정식은'i개의 케이크를 취하든 안 취하든'에서 나온다.
code:
4
#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
#define F first
#define S second
#define mod 1000000007
const int INF = 1<<30;
const int N = 810;
int dp[N][N];
pair<int,int> pr[N];
bool cmp(pair<int,int> i, pair<int,int> j) {return i>j;}
int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i=1; i<=n; i++)
scanf("%d%d", &pr[i].S,&pr[i].F);
sort(pr+1,pr+n+1,cmp); //
memset(dp, 0, sizeof(dp));
for(int i=1; i<=n; i++)
{
for(int j=1; j<=i/2; j++)
{
dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]+pr[i].S);
}
}
printf("%d
", dp[n][n/2]);
}
return 0;
}
각 층의 상태가 상층 상태에서 옮겨오는 것을 볼 수 있기 때문에 여기는 스크롤 수조로 1차원 공간을 줄일 수 있고 1차원을 반복적으로 이용하여 조작할 수 있다.2차원이라면 이전 과정이 상층에 영향을 주지 않고 1차원이라면 dp[j]=max(dp[j], dp[j-1]+...)를 볼 수 있다.이렇게 하면 사실 문제가 있다. 문제는 j상태를 갱신할 때 2차원 상층에 해당하는 j상태를 덮어쓰는 것이다. 그러면 j+1상태를 갱신할 때 원래의 j상태에서 옮겨온 것이 아니다.그래서 우리는 순환의 순서를 좀 돌려서 영향을 주지 않을 수 있다.code:
#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
#define F first
#define S second
#define mod 1000000007
const int INF = 1<<30;
const int N = 810;
int dp[N];
typedef pair<int,int> pii;
pii pr[N];
bool cmp(pii i, pii j) {return i>j;}
int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i=1; i<=n; i++)
scanf("%d%d", &pr[i].S,&pr[i].F);
sort(pr+1,pr+n+1,cmp);
memset(dp, 0, sizeof(dp));
for(int i=1; i<=n; i++)
{
for(int j=i/2; j>=1; j--)
{
dp[j] = max(dp[j],dp[j-1]+pr[i].S);
}
}
printf("%d
", dp[n/2]);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.