标签:动态 训练 int long 蓝桥 maxn 权值 include dp
入门
数组分组
题意:
一个数组可被分为n组,整个数组的权值被定义为各组内数字之积对1000取模后的总和,求数组的最大权值
思路:
我们用dp[i]表示前i个数分组的最大权值,对于位置i,我们可以枚举最后一个分组的起始位置为j,计算i,j之间的权值,然后更新dp[i]即可。
为了避免过多的计算,我们需要预处理出来每个区间的乘积对1000取模的结果。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e3+100, mod = 1000; int n, a[maxn], dp[maxn], pre[maxn][maxn]; int main(){ scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= n; i++){ pre[i][i] = a[i]; for(int j = i+1; j <= n; j++) pre[i][j] = (pre[i][j-1]*a[j])%mod; } dp[1] = a[1]; for(int i = 2; i <= n; i++){ for(int j = 0; j < i ; j++) dp[i] = max(dp[i], dp[j]+pre[j+1][i]); } printf("%d", dp[n]); }View Code
墙壁涂色
题意:
一个环形的房间被分成n块,每块的颜色可以为R、G、B,但是相邻两快的颜色必须不同,求涂色的方案数
思路:
这是道递推的题目,用dp[i]表示长度为i的方案数
递推的本质:用已知推未知,寻找前后项之间的关系。仔细观察发现可以分为两种情况,当第1项和第n-1项不同色时,第n项只能取一种颜色;当两者取相同颜色时,第n项可以取两种颜色,于是得到递推表达式:dp[n] = dp[n-1] + 2*dp[n-2]
最后注意初始化的时候需要初始化dp[0]、dp[1]、dp[2](原因稍加思考便知),并且输出使用long long否则溢出
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define ll long long using namespace std; const int maxn = 1e5+100; ll n, a[maxn], dp[maxn]; int main(){ scanf("%lld", &n); dp[1] = 3, dp[2] = 6, dp[3] = 6; for(int i = 4; i <= n; i++) dp[i] = dp[i-1] + 2*dp[i-2]; printf("%lld", dp[n]); }View Code
标签:动态,训练,int,long,蓝桥,maxn,权值,include,dp 来源: https://www.cnblogs.com/wizarderror/p/14641429.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。