当前位置:编程学习 > C/C++ >>

SRM 585

250 :

递推,从左下角到右下角走一条,剩下的都是子结构


 

const int mod =  1000000007; 
long long dp[1000010] , s[1000010]; 
class  
TrafficCongestion{ 
    public : 
    int theMinCars(int n) { 
        long long ans = 0; 
        dp[0] = 1; 
        dp[1] = 1; s[0] = 1; s[1] =2; 
        REP(i,2,n) { 
            dp[i] = (1 + s[i-2] + s[i-2] ) % mod; 
            s[i] = (s[i-1] + dp[i]) % mod; 
        } 
        return dp[n]; 
    } 
}; 

const int mod =  1000000007;
long long dp[1000010] , s[1000010];
class
TrafficCongestion{
    public :
    int theMinCars(int n) {
        long long ans = 0;
        dp[0] = 1;
        dp[1] = 1; s[0] = 1; s[1] =2;
        REP(i,2,n) {
            dp[i] = (1 + s[i-2] + s[i-2] ) % mod;
            s[i] = (s[i-1] + dp[i]) % mod;
        }
        return dp[n];
    }
};

500pt:


给你从小到大n种数字的个数,让你判断由全部的数字组成的序列中lisnum = k的有多少个。。lisnum就是一个序列递增的段数

dp[i][j] 表示前i种数产生了j个lisnum的数量,然后放上i+1种数时需要枚举放几个数放在那些递增段的后面,这样子放并不会增加lisnum的数量,假设放t个数在递增段的后面

那么现在总共有sum+1-j+t个位置是会增加lisnum的,我们要将剩下的cnt[i+1] - t个数放到这些位置去,就是高中的隔板法了


 

?#include <cstdio>  
#include <cstring>  
#include <vector>  
using namespace std; 
typedef long long lld; 
const int mod = 1000000007; 
int dp[2][1500]; 
int C[1500][1500]; 
class LISNumber { 
    public : 
    int count(vector <int> cnt, int K) { 
        C[0][0] = 1; 
        for(int i = 1; i < 1500; i++) { 
              C[i][0] = C[i][i] = 1; 
             for(int j = 1; j < i; j++) { 
                  C[i][j] = C[i-1][j] + C[i-1][j-1]; 
                  if(C[i][j] >= mod) C[i][j] -= mod; 
             } 
        } 
        dp[0][cnt[0]] = 1; int sum=cnt[0]; 
        for(int i = 1; i < cnt.size(); i++) { 
            memset(dp[i&1],0,sizeof(dp[0])); 
            for(int j = 0; j <= K; j++) if(dp[(i-1)&1][j]) { 
                for(int t = 0; t <= min(cnt[i],j); t++) { 
                    int box = sum + 1 - j + t; 
                    int balls = cnt[i] - t; 
                    dp[i&1][j+balls] += (lld)dp[(i-1)&1][j] * C[j][t] % mod * C[box-1+balls][balls] % mod; 
                    if(dp[i&1][j+balls] >= mod) dp[i&1][j+balls] -= mod; 
                } 
            } 
            sum+=cnt[i]; 
        } 
        return dp[(cnt.size()-1)&1][K]; 
    } 
}; 
 
 
// Powered by FileEdit  
// Powered by TZTester 1.01 [25-Feb-2003]  
// Powered by CodeProcessor 

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef long long lld;
const int mod = 1000000007;
int dp[2][1500];
int C[1500][1500];
class LISNumber {
    public :
    int count(vector <int> cnt, int K) {
        C[0][0] = 1;
        for(int i = 1; i < 1500; i++) {
              C[i][0] = C[i][i] = 1;
             for(int j = 1; j < i; j++) {
                  C[i][j] = C[i-1][j] + C[i-1][j-1];
                  if(C[i][j] >= mod) C[i][j] -= mod;
             }
        }
        dp[0][cnt[0]] = 1; int sum=cnt[0];
        for(int i = 1; i < cnt.size(); i++) {
            memset(dp[i&1],0,sizeof(dp[0]));
            for(int j = 0; j <= K; j++) if(dp[(i-1)&1][j]) {
                for(int t = 0; t <= min(cnt[i],j); t++) {
                    int box = sum + 1 - j + t;
                    int balls = cnt[i] - t;
                    dp[i&1][j+balls] += (lld)dp[(i-1)&1][j] * C[j][t] % mod * C[box-1+balls][balls] % mod;
                    if(dp[i&1][j+balls] >= mod) dp[i&1][j+balls] -= mod;
                }
            }
            sum+=cnt[i];
        }
        return dp[(cnt.size()-1)&1][K];
    }
};


// Powered by FileEdit
// Powered by TZTester 1.01 [25-Feb-2003]
// Powered by CodeProcessor

 


 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,