首页 > 代码库 > Codeforces Round #247 (Div. 2)
Codeforces Round #247 (Div. 2)
A。水题。
遍历字符串对所给的对应数字求和即可。
B。简单题。
对5个编号全排列,然后计算每种情况的高兴度,取最大值。
C。dp。
设dp[n][is]表示对于k-trees边和等于n时,如果is==1表示存在边至少为d的边,如果is==0表示不存在边至少为d的边。
初始状态dp[0][0]=1。
//和为n且不存在至少为d的边的状态可以由所有不存在至少为d的边加一条小于d的边转移而来。
dp[n][0]=dp[n-1][0]+dp[n-2][0]+……+dp[n-(d-1)][0]
//和为n且存在至少为d的边的状态可以由 存在至少为d的边加一条小于d的边转移而来,无论是否存在至少d的边的状态加一条大于等于d的边 转移而来。
dp[n][1]=dp[n-1][1]+dp[n-2][1]+……+dp[n-(d-1)][0]+(dp[n-d][1]+dp[n-d][0])+(dp[n-(d+1)][1]+dp[n-(d+1)][0])+……+(dp[n-(d+1)][1]+dp[n-(d+1)][0])+……+(dp[n-k][1]+dp[n-k][0])
这个题状态设计的很巧妙,可以很好的降低时间复杂度。
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <cstring> #include <string> #define mod 1000000007 #define ll long long using namespace std; ll dp[105][105]; int n,k,d; int main() { cin>>n>>k>>d; dp[0][0]=1; for(int i=1; i<=n; ++i) { for(int j=1; j<d&&i-j>=0; ++j) { dp[i][0]+=dp[i-j][0]; dp[i][0]%=mod; } for(int j=1; j<=k&&i-j>=0; ++j) { if(j<d) dp[i][1]+=dp[i-j][1]; else dp[i][1]+=dp[i-j][1]+dp[i-j][0]; dp[i][1]%=mod; } } cout<<dp[n][1]<<endl; return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。