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++ ,