• AtCoder Beginner Contest 163


    题目链接

    D:
    看样例+分析得知,假设现在要选(i)个,那么能达到的最大的值就是(sum_{i_1}=sum^{n}_{x=n-i+1}{x}), 最小值就是(sum_{i_2}=sum^{i-1}_{x=0}{x}),那么每次可选择的数量就是(sum_1-sum_2+1),那么答案就为(sum_{i=k}^{n+1}({sum_{i_1}-sum_{i_2} + 1}))

    #include<bits/stdc++.h>
    using namespace std;
    #define ms(x,y) memset(x, y, sizeof(x))
    #define lowbit(x) ((x)&(-x))
    #define sqr(x) ((x)*(x))
    typedef long long LL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const LL MOD = 1e9+7;
    
    void run_case() {
        int n, k;
        cin >> n >> k;
        LL ans = 0;
        for(int i = k; i <= n+1; ++i) {
            LL t1 = 1LL*(i-1)*i/2;
            LL t2 = 1LL*(n+n-i+1)*i/2;
            (ans += t2 - t1 + 1) %= MOD;
        }
        cout << ans;
    }
    
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0);
        cout.flags(ios::fixed);cout.precision(9);
        //int t; cin >> t;
        //while(t--)
        run_case();
        cout.flush();
        return 0;
    }
    

    E:
    一开始用贪心做,将(A_i)从大到小排序,每次都放在端点,但是样例2、3单纯用该策略是不行的,样例3中,若选用贪心策略,得:
    (111556),但是使得最大值的方法为: (611155), 第二种方法时(6)就不是最优,所以应该根据数据范围想到该题为DP问题,但是放的策略肯定也是放在两端为最优,那么可以放在某个区间的两端,可以联想到区间dp
    (dp_{i,j})为闭区间([i,j])还未被选择时,已经选择的最优答案,得到状态转移:
    (dp_{i,j} = max(dp_{i,j+1}+A_k*|j+1-pos_k|, dp_{i-1, j}+A_k*|i-1-pos_k|), k = n-(j-i+1))(k)表示当前选择是第几个
    最终答案就是(max(dp_{i,i-1}), iin [1, n])

    #include<bits/stdc++.h>
    using namespace std;
    #define ms(x,y) memset(x, y, sizeof(x))
    #define lowbit(x) ((x)&(-x))
    #define sqr(x) ((x)*(x))
    typedef long long LL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    
    
    void run_case() {
        int n; cin >> n;
        vector<pll> a;
        for(int i = 1; i <= n; ++i) {
            LL t; cin >> t;
            a.emplace_back(t, 1LL*i);
        }
        sort(a.begin(), a.end(), [&](pll a, pll b) {
            return a.first > b.first;
        });
        vector<vector<LL>> dp(n+2, vector<LL>(n+2));
        for(int i = 1; i <= n; ++i) {
            for(int j = 0; j <= i; ++j) {   // len = r - l + 1, len = n - i
                int l = j+1, r = n - i + l - 1;
                if(r+1<=n) dp[l][r] = max(dp[l][r], dp[l][r+1]+abs(r+1-a[i-1].second)*a[i-1].first);
                if(l-1>=1) dp[l][r] = max(dp[l][r], dp[l-1][r]+abs(l-1-a[i-1].second)*a[i-1].first);
            }
        }
        LL ans = 0;
        for(int i = 1; i <= n; ++i) ans = max(ans, dp[i][i-1]);
        cout << ans;
    }
    
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0);
        cout.flags(ios::fixed);cout.precision(9);
        //int t; cin >> t;
        //while(t--)
        run_case();
        cout.flush();
        return 0;
    }
    

    F:
    我先放个坑在这里

  • 相关阅读:
    Java内存泄漏分析系列之七:使用MAT的Histogram和Dominator Tree定位溢出源
    Java内存泄漏分析系列之六:JVM Heap Dump(堆转储文件)的生成和MAT的使用
    Java内存泄漏分析系列之五:常见的Thread Dump日志案例分析
    Java内存泄漏分析系列之四:jstack生成的Thread Dump日志线程状态
    Java内存泄漏分析系列之三:jstat命令的使用及VM Thread分析
    Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析
    Java内存泄漏分析系列之一:使用jstack定位线程堆栈信息
    安全框架Shiro
    JDK动态代理与CGLib动态代理
    解读分库分表中间件Sharding-JDBC
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/13061092.html
Copyright © 2020-2023  润新知