UESTC第十四届校赛A题解题报告
2016-04-07 19:32
441 查看
太弱,什么都不会(Qrz)
给你一个n,然后你要用一个序列构成0到n的所有数(构成方法就是从序列中选若干个数加起来)问你有多少种这样的序列,{1,2,3}和{1,3,2}是相同的序列
首先,看下n范围5000,复杂度肯定是n^2打表。
然后赛上各种推不出状态。。。
其实,肯定有一维状态要表示整个序列的和,那么就是dp[i],i为整个序列的和的方法数。然后尝试转移会发现很迷茫。。显然再加一维,考虑到对整个序列排个序之后,我们只放大于等于整个序列最大元素的数,那么又肯定要有一维状态来表示当前序列的最大元素。
最后dp[i][j]表示,整个序列的和为i,且序列中最大元素为j的方法数。
接下来我们考虑转移,假设dp[i][j]正确且已知,那么dp[i][j]已经能够表示0-i的所有数,考虑接下来我们将在集合里添加的数k,k肯定大于等于j,但是当k大于i+1的时候,整个序列是无法表示i+1的,因此j<=k<=i+1
因此dp[i+k][k] += dp[i][j];
这样,我们发现复杂度是n^3,状态需要修改下,使得能让我们预处理降低一维复杂度,看看转移状态,第二维的k是显然没法改变的,于是我们尝试改变第一维。我们发现,i+k是与k有关的,于是定义状态dp[i][j]表示整个序列的和为i+j,且序列中最大元素为j的方法数,于是有转移dp[i+j][k] += dp[i][j] (j <= k <= i+j+1)
然后我们不必要每次都加,直接dp[i+j][j] += dp[i][j], dp[i+j][i+j+2] -= dp[i][j],每次再求个前缀和即可
给你一个n,然后你要用一个序列构成0到n的所有数(构成方法就是从序列中选若干个数加起来)问你有多少种这样的序列,{1,2,3}和{1,3,2}是相同的序列
首先,看下n范围5000,复杂度肯定是n^2打表。
然后赛上各种推不出状态。。。
其实,肯定有一维状态要表示整个序列的和,那么就是dp[i],i为整个序列的和的方法数。然后尝试转移会发现很迷茫。。显然再加一维,考虑到对整个序列排个序之后,我们只放大于等于整个序列最大元素的数,那么又肯定要有一维状态来表示当前序列的最大元素。
最后dp[i][j]表示,整个序列的和为i,且序列中最大元素为j的方法数。
接下来我们考虑转移,假设dp[i][j]正确且已知,那么dp[i][j]已经能够表示0-i的所有数,考虑接下来我们将在集合里添加的数k,k肯定大于等于j,但是当k大于i+1的时候,整个序列是无法表示i+1的,因此j<=k<=i+1
因此dp[i+k][k] += dp[i][j];
这样,我们发现复杂度是n^3,状态需要修改下,使得能让我们预处理降低一维复杂度,看看转移状态,第二维的k是显然没法改变的,于是我们尝试改变第一维。我们发现,i+k是与k有关的,于是定义状态dp[i][j]表示整个序列的和为i+j,且序列中最大元素为j的方法数,于是有转移dp[i+j][k] += dp[i][j] (j <= k <= i+j+1)
然后我们不必要每次都加,直接dp[i+j][j] += dp[i][j], dp[i+j][i+j+2] -= dp[i][j],每次再求个前缀和即可
// // Created by Running Photon on 2016-04-07 // Copyright (c) 2015 Running Photon. All rights reserved. // #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <sstream> #include <set> #include <vector> #include <stack> #define ALL(x) x.begin(), x.end() #define INS(x) inserter(x, x,begin()) #define ll long long #define CLR(x) memset(x, 0, sizeof x) using namespace std; const int inf = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 1e6 + 10; const int maxv = 5e3 + 10; const double eps = 1e-9; int sum[maxv]; int dp[maxv][maxv]; int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif // ios_base::sync_with_stdio(0); dp[0][1] = 1; dp[0][2] = -1; int n = 5000; for(int i = 0; i <= n; i++) { for(int j = 1; j <= n; j++) { dp[i][j] = (dp[i][j] + dp[i][j-1]) % MOD; } for(int j = 1; j <= n; j++) { if(!dp[i][j]) continue; dp[i+j][j] = (dp[i+j][j] + dp[i][j]) % MOD; dp[i+j][i+j+2] = (dp[i+j][i+j+2] - dp[i][j]) % MOD; } } for(int i = 0; i <= n; i++) { for(int j = 0; j <= n; j++) { if(i + j > n) break; sum[i+j] = (sum[i+j] + dp[i][j]); } } while(scanf("%d", &n) != EOF) { printf("%d\n", sum ); } return 0; }
相关文章推荐
- Leetcode_300_Longest Increasing Subsequence
- 动态计算UITableViewCell高度详解
- getParameter()和getParameterValue()的区别
- uva11324 The Largest Clique --- 强连通+dp
- APUE------线程同步
- iOS开发之UITableView的使用
- UI控件无法显示的原因小结
- iOS UIView动画效果 学习笔记
- LeetCode334. Increasing Triplet Subsequence完美解答
- (Caffe)基本类DataReader、QueuePair、Body(四)
- Android高级UI之ViewPager实现页卡的最新方法-简洁的TabLayout
- uint8_t / uint16_t / uint32_t /uint64_t
- ie浏览器强制开启怪异模式(Quirks Mode)的解决方法
- CoAP Request and Response Rules
- Could not find com.android.tools.build:gradle:1.3.0.
- android studio 构建系统基础build
- 3D Slicer+Qt-easy-build+VS2013
- Android学习笔记---第五天---基础UI组件---AnalogClock&TextClock&Chronometer(时钟与简单的计时器)
- 利用UEditor上传图片的注意点
- Access restriction: The type JFrame is not accessible due to restriction on required 错误