zoukankan      html  css  js  c++  java
  • #417 Div2 Problem C Sagheer and Nubian Market (二分 && std::accumulate)

    题目链接 : http://codeforces.com/problemset/problem/812/C

    题意 : 给你 n 件物品和你拥有的钱 S, 接下来给出这 n 件物品的价格, 这些物品的价值不是固定不变的, 价格的变化公式是 a[i]+k*i (i代表第 i 件物品, k 代表你选择买的物品数量, a[i]为物品的底价), 现问你最多能够买多少件物品和所买物品总和, 输出时应该使得所买物品总和尽量小

    分析 : 如果我当前能买 k 件物品, 那我肯定能买数量小于 k 的物品, 如果我当前买不起 k 件物品, 那我肯定也不能买比 k 件要多的物品。所以可以考虑二分解法, 在1~n之间二分查找 k, 这里需要注意的是, 在二分的过程中应该需要对当前的价格进行更新和排序, 才能保证最后输出的物品总和尽量小!

    技巧 : 这里有需要计算数组前 k 个的和, 可以考虑使用 std::accumulate(begin, end, base), 代表从数组的arr[begin]加到arr[end]的和再加上base, 也就是在base的基础上求arr数组的begin~end的和, 这里有详细介绍(值得一提的是复杂度是 O(n) ) http://classfoo.com/ccby/article/Y749fK

    std::accumulate函数应用举例 : 

    #include <vector>
    #include <numeric>
    #include <functional>
    #include <iostream>
    
    using namespace std;
    
    int main( ) 
    {
    
       vector <int> v1, v2( 20 );
       vector <int>::iterator Iter1, Iter2;
    
       int i;
       for ( i = 1 ; i < 21 ; i++ )
       {
          v1.push_back( i );
       }
    
       cout << "最初向量v1中个元素的值为:
     ( " ;
       for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
          cout << *Iter1 << " ";
       cout << ")." << endl;
    
       // accumulate函数的第一个功能,求和
       int total;
       total = accumulate ( v1.begin ( ) , v1.end ( ) , 0 );
    
       cout << "整数从1到20的和为: " 
            << total << "." << endl;
    
       // 构造一个前n项和的向量
       int j = 0, partotal;
       for ( Iter1 = v1.begin( ) + 1; Iter1 != v1.end( ) + 1 ; Iter1++ )
       {
          partotal = accumulate ( v1.begin ( ) , Iter1 , 0 );
          v2 [ j ] = partotal;
          j++;
       }
    
       cout << "前n项和分别为:
     ( " ;
       for ( Iter2 = v2.begin( ) ; Iter2 != v2.end( ) ; Iter2++ )
          cout << *Iter2 << " ";
       cout << ")." << endl << endl;
    
       // accumulate函数的第二个功能,计算连乘积
       vector <int> v3, v4( 10 );
       vector <int>::iterator Iter3, Iter4;
    
       int s;
       for ( s = 1 ; s < 11 ; s++ )
       {
          v3.push_back( s );
       }
    
       cout << "向量v3的初始值分别为:
     ( " ;
       for ( Iter3 = v3.begin( ) ; Iter3 != v3.end( ) ; Iter3++ )
          cout << *Iter3 << " ";
       cout << ")." << endl;
    
       int ptotal;
       ptotal = accumulate ( v3.begin ( ) , v3.end ( ) , 1 , multiplies<int>( ) );
    
       cout << "整数1到10的连乘积为: " 
            << ptotal << "." << endl;
    
       // 构造一个前n项积的向量
       int k = 0, ppartotal;
       for ( Iter3 = v3.begin( ) + 1; Iter3 != v3.end( ) + 1 ; Iter3++ ) {
          ppartotal = accumulate ( v3.begin ( ) , Iter3 , 1 , multiplies<int>( ) );
          v4 [ k ] = ppartotal;
          k++;
       }
    
       cout << "前n项积分别为:
     ( " ;
       for ( Iter4 = v4.begin( ) ; Iter4 != v4.end( ) ; Iter4++ )
          cout << *Iter4 << " ";
       cout << ")." << endl;
    }
    View Code

    瞎想 : 一开始是在想是否能用背包做, 事实证明在S那个数据量下是不可能的, 而且背包的话, 这里要求的是总和尽量小。

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int maxn = 1e5+10;
    LL arr[maxn], change[maxn];
    LL n, s;
    LL cal(LL k)
    {
        for(int i=1; i<=n; i++) change[i] = i*k+arr[i];
        sort(change+1, change+1+n);
        LL ans = accumulate(change+1, change+1+k, 0LL);
        return ans;
    }
    int main(void)
    {
        scanf("%lld %lld", &n, &s);
        for(int i=1; i<=n; i++)
            scanf("%lld", &arr[i]);
        LL L = 1, R = n, mid;
        while(L<=R){
            mid = L + ((R-L)>>1);
            LL sum = cal(mid);
            if(sum <= s) L = mid + 1;
            else R = mid - 1;
        }
        if(L==1){
            puts("0 0");
            return 0;
        }
        L--;
        printf("%lld %lld
    ", L, cal(L));
        return 0;
    }
    View Code
  • 相关阅读:
    《应用Yii1.1和PHP5进行敏捷Web开发》学习笔记(转)
    YII 小模块功能
    Netbeans代码配色主题大搜集
    opensuse 启动巨慢 解决方法 90s多
    opensuse 安装 网易云音乐 rpm netease music
    linux qq rpm deb opensuse
    openSUSE 安装 alien
    第一行代码 Android 第2版
    Android Studio AVD 虚拟机 联网 失败
    docker error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.29/containers/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuratio
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/6938958.html
Copyright © 2011-2022 走看看