CF 1141 F Same Sum Blocks

  https://codeforces.com/contest/1141/problem/F2

题意:

  给一串数字,然后从中挑选出一些连续的小段,使每个片段的和相等,每小段至少一个数字.

  小段之间不能相交.

  找到片段数目最多的方法.

思路:

  数据量不大, n<1500, n^2也不会T.

  贪心, 先n*n将所有片段的和求出来, 用和当key, 保存在一个map里, 记录左右节点的序号, 每个key下都有很多种片段, 这些片段可以放在一个vector里面.

  在这个vectot里面全是和相同的pair(i,j), 去找最大不相交的片段数目.(贪心)

 

PS:

  贪心找最大不相交片段数目的时候, 一定要思考清楚怎么找得到的片段数目才是最多的.   

// 1141F 同解

#include <bits/stdc++.h>
using namespace std;

bool cmp(pair<int,int> a, pair<int,int> b)
{
    return a.first > b.first;
}
bool cmp_2(pair<int,int> a, pair<int,int> b)
{
    return a.first < b.first;
}
map<int, vector<pair<int,int>>> mp;
map<int, vector<pair<int,int>>> ans;
int p[2000];
int sum[2000];

int main()
{
    //freopen("test_data.txt","r",stdin);
    // INPUT
    int n;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cin>>p[i];
        sum[i+1] = sum[i]+p[i];
    }
    // DEAL
    int su =0;
    for(int i=1; i<=n; i++)
    {
        for(int j=i; j<=n; j++)
        {
            su = sum[j]-sum[i-1];
            mp[su].push_back(make_pair(i,j));            
        }
        
    }
    //cout<<"map prepared!"<<endl;
    
    int max_cnt = 0;
    int index = 0;
    for(auto &itor : mp)
    {  
        //cout<<"index : "<<itor.first<<endl; 
        int cnt = 0;
        int pre = 500001;
        sort(itor.second.begin(), itor.second.end(), cmp);
        for(auto &it: itor.second)
        {
            //if (itor.first == -5)
                //cout<<"add new :"<<it.first<<"," <<it.second<<endl;
            if(it.second<pre)
            {  
                cnt++;
                pre = it.first;
                ans[itor.first].push_back(it);
            }
            if(cnt > max_cnt)
            {
                //cout<<"cnt = "<<cnt<<endl;
                max_cnt = cnt;
                index = itor.first;
            }
        }
    }
    //cout<<"prepare to out put!"<<endl;
    // OUTPUT
    //cout<<"index = "<<index<<endl;
    sort(ans[index].begin(), ans[index].end(), cmp_2);
    cout<<ans[index].size()<<endl;
    for(auto &itor: ans[index])
        cout<<itor.first<<" "<<itor.second<<endl;
    
    return 0;
}

 

  

posted @ 2019-03-26 19:45  dutbyy  阅读(109)  评论(0)    收藏  举报