zoukankan      html  css  js  c++  java
  • DP

    DP - [USACO16OPEN] - 262144P

    (dp[i][j])表示从第i个数开始,向右合成数j,最后一个用到的数(右端点)的位置

    假如我们想要从第(i)个数开始,合成数j,首先需要(dp[i][j-1] eq 0),因为只有先合成(j-1)才能得到(j)。此外,还需要(dp[dp[i][j-1]+1][j-1] eq 0),这是因为,除了这一段合成(j-1),还需要下一段合成(j-1),才能将两个(j-1)合成一个(j)。因此,可知dp过程:

    // init
    for(int i = 1; i <= n; ++i)
      	cin >> a[i];
    
    // init dp
    for(int i = 1; i <= n; ++i)
      	dp[i][a[i]] = i;
    
    // dp
    for(int i = n; i >= 1; --i){
      	for(int j = a[i]+1; j <= 60; ++j){
          	if(dp[i][j])
        }
    }
    

    完整代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 262144+5;
    
    int n;
    int a[N];
    int dp[N][80]; // 从第i个数开始, 向右边合成数j,得到的右端点为x
    
    int main(){
        cin >> n;
        
        for(int i = 1; i <= n; ++i)
            cin >> a[i];
        
        for(int i = 1; i <= n; ++i){
            dp[i][a[i]] = i;
        }
        
        for(int i = n-1; i >= 1; --i){
            for(int j = a[i]+1; j <= 60; ++j){
                if(dp[i][j-1] && dp[i][j-1]+1 <= n && dp[dp[i][j-1]+1][j-1])
                    dp[i][j] = dp[dp[i][j-1]+1][j-1];
            }
        }
    
        int ans = 0;
    
        
        for(int j = 1; j <= 60; ++j){
            for(int i = 1; i <= n; ++i){
                if(dp[i][j]){
                    ans = max(ans, j);
                    break;
                }
            }
        }
    
        cout << ans << endl;
        return 0;
    }
    
    
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    Beta版使用说明
    【每日scrum】NO.7
    【每日scrum】NO.6
    【每日scrum】NO.5
    【每日scrum】NO.4
    【每日scrum】NO.3
    【每日scrum】NO.2
    【每日scrum】NO.1
    运行及总结
    测试与调试
  • 原文地址:https://www.cnblogs.com/popodynasty/p/14658585.html
Copyright © 2011-2022 走看看