E - Election of a Mayor Gym - 100513E(DP)

The Berland capital is preparing for mayoral election. There are two candidates for the position: the current mayor and his rival. The rival is a serious competitor, and it’s not easy for current mayor to win the election.

The candidate will be declared the winner if he wins at more than a half of all polling stations. The results of the polling stations are supplied independently. The station winner is the candidate who gets more than a half of the votes of this station. No candidate is declared a winner of a polling station if both candidates have got the same number of votes at this station. Similarly, no candidate is declared a winner of the election if both candidates won at the same number of polling stations.

All eligible voters are going to take part in the election and have already decided whom to give their vote to. The campaign headquarters of the current mayor has collected data from all n stations of the city, and now for every station it is known how many people will vote for the current mayor and how many people will vote for his opponent.

The results have been disappointing for the current mayor, but his staff came up with a way to win the election. It was suggested to merge some pairs of polling stations in such a way that the current mayor will become the election winner. However, (for the sake of credibility), the proposed plan must comply with two conditions. Firstly, it is possible to merge only the pairs of stations with adjacent numbers (i.e., station j may be merged with either station j - 1, or with station j + 1). The resulting station cannot be merged again. Secondly, the number of such mergers for obvious reasons must be as few as possible.

Your task is to help the current mayor’s campaign headquarters and produce such plan.

Input
The first line contains single integer n (2 ≤ n ≤ 2·105) — the number of the polling stations.

Each of the following n lines contains two integers m j and r j (0 ≤ m j, r j ≤ 105) — the number of voters at station j who plan to vote for the current mayor and his rival correspondingly.

Output
If current mayor cannot win the election at any condition, print a single number  - 1 to the first line.

Otherwise, to the first line print an integer u — the minimum number of polling station mergers the current mayor needs to perform in order to win. To each of the next u lines print a pair of integers — the numbers of the merged stations. The pairs as well as the numbers within each pair can be printed in any order. If there are multiple solutions, print any of them.

Examples
Input
7
15 8
8 10
14 14
12 13
13 12
21 10
20 30
Output
2
1 2
6 7
Input
2
1 5
5 1
Output
-1
Input
2
10 9
15 7
Output
0

题意:
两个人竞选市长,有n个区域,每个区域选票大于一半才能获得这个区域。获得的区域大于一半才能获胜。你可以合并一些区域,使得现任市长赢得选举。

思路:
定义 d p [ i ] [ 0 / 1 ] dp[i][0/1] ,代表选完前i个区域,第i个区域不合并/合并能删除的最大区域数。而需要删除的区域数一开始就可以计算出来。所以算完dp最后回溯即可。但是合并有条件,不能减少获胜区域。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>

using namespace std;

const int maxn = 3e5 + 7;

int dp[maxn][2];
pair<int,int> pre[maxn][2];
int m[maxn],r[maxn];

vector<int>ans;
int main() {
    int n;scanf("%d",&n);
    int x1 = 0,x2 = 0;
    for(int i = 1;i <= n;i++) {
        scanf("%d%d",&m[i],&r[i]);
        if(m[i] > r[i]) {
            x1++;
        }
        else x2++;
    }
    if(x1 > x2) {
        printf("0\n");
        return 0;
    }
    
    int num = x2 - x1 + 1;
    
    int pos1 = 0,pos2 = 0;
    for(int i = 2;i <= n;i++) {
        dp[i][0] = max(dp[i - 1][1],dp[i - 1][0]);
        
        if(dp[i - 1][1] > dp[i - 1][0]) {
            pre[i][0] = {i - 1,1};
        }
        else
            pre[i][0] = {i - 1,0};
        
        if((!(m[i] > r[i] && m[i - 1] > r[i - 1]) && (m[i] + m[i - 1] > r[i] + r[i - 1])) || (m[i] <= r[i] && m[i - 1] <= r[i - 1])) {
            dp[i][1] = max(dp[i - 2][1],dp[i - 2][0]) + 1;
            if(dp[i - 2][1] > dp[i - 2][0]) {
                pre[i][1] = {i - 2,1};
            }
            else {
                pre[i][1] = {i - 2,0};
            }
            
        }
        if(dp[i][1] == num) {
            pos1 = i;
            pos2 = 1;
            break;
        }
    }
    
    if(pos1 == 0) {
        printf("-1\n");
        return 0;
    }
    
    for(int i = pos1;i;) {
        pair<int,int>now = pre[i][pos2];
        if(pos2 == 1) {
            ans.push_back(i);
        }
        pos2 = now.second;
        i = now.first;
    }
    
    printf("%d\n",num);
    
    for(int i = ans.size() - 1;i >= 0;i--) {
        printf("%d %d\n",ans[i] - 1,ans[i]);
    }
    return 0;
}
原创文章 930 获赞 38 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/106057946