dp
给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除 答案对1e9+7取模
#include <bits/stdc++.h>
#define int long long
using namespace std;
//const int mod = 998244353;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
int dp[55][3];
void solve() {
string t;
cin >> t;
int l = t.size();
int m = 0;
for (int i = 0; i < 55; ++i)
dp[i][(t[i]-'0')%3] = 1;
for (int i = 0; i < l; ++i) {
m = (t[i] - '0') % 3;
for (int j = 0; j < 3; ++j) {
dp[i][j] += (dp[i - 1][j] + dp[i - 1][(j + 3 - m) % 3]) % mod;
}
}
cout << dp[l - 1][0] % mod << endl;
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
// cin >> _;
while (_--)
solve();
return 0;
}
牛牛喜欢整数序列,他认为一个序列美丽的定义是
1:每个数都在0到40之间
2:每个数都小于等于之前的数的平均值
具体地说:for each i, 1 <= i < N, A[i] <= (A[0] + A[1] + … + A[i-1]) / i.
3:没有三个连续的递减的数
现在给你一个序列,每个元素是-1到40,你可以将序列中的-1修改成任意的数,求你可以得到多少个美丽序列,答案对1e9+7取模
#include <bits/stdc++.h>
//#pragma GCC optimize(2)
#define int long long
using namespace std;
//const int mod = 998244353;
const int mod = 1e9 + 7;
const int maxn = 1e3 + 10;
int a[45];
int dp[45][45][3][1605];
void solve() {
int n;
cin>>n;
for (int i = 1; i <=n; ++i) cin>>a[i];
if(a[1]==-1){
for (int i = 0; i <=40; ++i) {
dp[1][i][1][i]=1;
}
} else dp[1][a[1]][1][a[1]]=1;
for (int i = 2; i <=n; ++i) {
if(a[i]==-1){
///枚举当前数是啥
for (int j = 0; j <=40; ++j) {
///枚举前一个数是啥
for (int pj = 0; pj <=40; ++pj) {
for (int k = j*(i-1); k <=1600-j; ++k) {
if (j>=pj){
dp[i][j][1][k+j]=(dp[i][j][1][k+j]+dp[i-1][pj][1][k]+dp[i-1][pj][2][k])%mod;
} else{
dp[i][j][2][j+k]=(dp[i][j][2][k+j]+dp[i-1][pj][1][k])%mod;
}
}
}
}
} else{
for (int pj = 0; pj <=40; ++pj) {
for (int k = a[i]*(i-1); k <=1600-a[i]; ++k) {
if (a[i]>=pj){
dp[i][a[i]][1][k+a[i]]=(dp[i][a[i]][1][k+a[i]]+dp[i-1][pj][1][k]+dp[i-1][pj][2][k])%mod;
} else{
dp[i][a[i]][2][a[i]+k]=(dp[i][a[i]][2][k+a[i]]+dp[i-1][pj][1][k])%mod;
}
}
}
}
}
int sum=0;
for (int j = 0; j <=1600; ++j) {
for (int i = 0; i <=40; ++i) {
sum=(sum+dp[n][i][1][j])%mod;
sum=(sum+dp[n][i][2][j])%mod;
}
}
cout<<sum;
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;
struct node{
int score;
int down;
int time;
bool operator <(const node& yxj) const {
return down*1.0/time>yxj.down*1.0/yxj.time;
}
}nc[55];
int dp[maxn];
void solve() {
int n,m;
cin>>n>>m;
for (int i = 0; i < n; ++i)
cin>>nc[i].score;
for (int i = 0; i < n; ++i)
cin>>nc[i].down;
for (int i = 0; i < n; ++i)
cin>>nc[i].time;
sort(nc,nc+n);
int max_=0;
for (int i = 0; i < n; ++i) {
for (int j = m; j >=nc[i].time; --j) {
dp[j]=max(dp[j],dp[j-nc[i].time]+nc[i].score-nc[i].down*j);
max_=max(max_,dp[j]);
}
}
cout<<max_;
}
signed main() {
cin.tie(), cout.tie();
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
}
给你一个数组R,包含N个元素,求有多少满足条件的序列A
使得
0 ≤ A[i] ≤ R[i]
A[0]+A[1]+…+A[N-1]=A[0] or A[1]… or A[N-1]
输出答案对1e9+9取模
数位dp
状态表示:DP[iI[j](i=62,j=1<<12)表示枚举到sum二进制的第i位时,R数组里各个数字的限制情况,这里特别解释下限制的意思,因为我们枚举SUM二进制时要考虑二进制上1的来源,设R1=10010(二进制),如果SUM的第五位是由A1的数字贡献的,既A1>=10000,那么当我们继续考虑第四位的1时,A1必然无法继续作出贡献,会导致A1超出R1的限制,直到枚举至第二位,它本身上界有1时,才能继续贡献,可是如果之前第5位的时候A1不贡献1,那么根据二进制,高位的1大于所有比它低位的1的和(10000>01111),既A1<10000,那么在考虑后面4,3,2,1位的时候,A1可以任意选择贡献1还是不贡献1,这就是限制与不限制的区别。至此J的含义已经清楚
J可以被当成一个12位的二进制数,如果第一位上是1则代表,A1是不受限制的,反之则受限,受限的Ai只能在其上届Ri有1的时候才能作出贡献。转移方程:假设枚举到第I位,限制状态是J,如果SUM该位二进制数取0,则在该位上是1的R[i],在之后的搜索中全部变成无限制,而如果取1,1的来源有两种情况,一种是R[I]被限制了,但这一位上有1,那么R[I]依旧保持限制,其他这一位上有1的变为无限制,第二种是R[I]没被限制,那么R[I]保持无限制,其他这一位上有1的也为无限制。当然之前就已经无限制的数字在之后依旧无限制,总计三种情况,记忆化搜索。
#include <stdio.h>
#include <cstring>
#include<deque>
#include <iostream>
#include<set>
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod=1e9+9;
int dp[63][1<<12];
long long R[12];
int n;
int dfs(int p,int limit){
if(p<0) return 1;
if(dp[p][limit]!=-1) return dp[p][limit];
int ans=0;//用来记录第P位上有1的R[i],用于后续的限制解除.
for(int i=1;i<=n;i++)
if(R[i]&((long long)1<<p))
ans|=(1<<i);
long long res=0;
res+=dfs(p-1,ans|limit);//如果第P位取0,所有ans记录的Ri全部解除限制ans|limit。
for(int i=1;i<=n;i++){
if(((long long)1<<i)&limit)//取1的时候,如果Ri已经无限制了,保持无限制,其他这一位上有1的也为无限制。当然之前就已经无限制的数字在之后依旧无限制
res+=dfs(p-1,ans|limit);
else if(!((1<<i)&limit)&&ans&(1<<i))//R[I]被限制了,但这一位上有1,那么R[I]依旧保持限制,其他这一位上有1的变为无限制
res+=dfs(p-1,(ans^(1<<i))|(limit));
}
dp[p][limit]=res%mod;
return dp[p][limit];
}
int main(){
memset(dp,-1,sizeof(dp));
cin>>n;
for(int i=1;i<=n;i++){
scanf("%lld",&R[i]);
}
dfs(61,0);
cout<<dp[61][0]<<endl;
return 0;
}
#include <bits/stdc++.h>
//#pragma GCC optimize(2)
#define int long long
using namespace std;
//const int mod = 998244353;
const int mod = 1e9+7;
const int maxn = 2e5 + 10;
int w[maxn];
int max_=0,sum=0;
int p=10007;
vector<int> g[maxn];
void solve() {
int n;
cin>>n;
for (int i = 1; i <n; ++i) {
int a,b;
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
for (int i = 1; i <=n; ++i) {
cin>>w[i];
}
for (int i = 1; i <=n; ++i) {
int mx=0,ans=0;
for(auto y:g[i]){
max_=max(max_,mx*w[y]);
sum+=ans*w[y];
sum%=p;
ans+=w[y];
mx=max(mx,w[y]);
}
}
cout<<max_<<" "<<(sum*2)%p<<"\n";
}
signed main() {
// ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;
//const int mod = 998244353;
const int inf = 1e18;
const int mod = 1e9 + 7;
const int maxn = 2e6 + 10;
const int N = 8e7 + 10000;
int a[maxn];
int dp[maxn];
void solve() {
int n;
cin>>n;
for (int i = 1; i <=n; ++i) {
int x;
cin>>x;
dp[i]=max(dp[i],dp[i-1]);
if (a[x]) dp[i]=max(dp[i],dp[a[x]]+1);
a[x]=i;
}
cout<<dp[n];
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;map<int,int>mp;
int main(){
int n;
cin>>n;
int ans=0;
mp.clear();
for(int i=0;i<n;i++){
int x;
cin>>x;
if(mp[x]){
mp.clear();
ans++;
}
mp[x]++;
}
cout<<ans<<endl;
}
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
#define int long long
typedef long long LL;
typedef long long ll;
const int INF = 0x3f3f3f3f;
//const int inf = 1e18;
const int mod = 998244353;
//const int mod = 1e9 + 7;
int gcd(int a, int b) { return !b ? a : gcd(b, a % b); }
const int maxn = 1e4 + 10;
const int N = 5e5 + 100;
map<string, set<string>> ma;
multiset<int> se;
queue<int> qu;
vector<int> v;
void solve() {
int n;
while (cin>>n){
int dp[maxn]={0};
int a[maxn]={0};
for (int i = 1,x; i <=n; ++i) {
cin>>x,a[x]++;
dp[i]= max(dp[i-1],a[0]-a[1]);
}
cout<<dp[n]+a[1]<<"\n";
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();//cout<<"\n";
}
return 0;
}
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
#define int long long
typedef long long LL;
typedef long long ll;
const int INF = 0x3f3f3f3f;
//const int inf = 1e18;
const int mod = 998244353;
//const int mod = 1e9 + 7;
int gcd(int a, int b) { return !b ? a : gcd(b, a % b); }
const int maxn = 1e6 + 10;
const int N = 5e5 + 100;
map<string, set<string>> ma;
multiset<int> se;
queue<int> qu;
vector<int> v;
int a[maxn];
int dp[maxn];
void solve() {
int n;
cin>>n;
for (int i = 1; i <=n; ++i) {
cin>>a[i];
for (int j = i-1; j >=0; j--) {
if (a[j]<=a[i])
dp[i]= max(dp[j]+1,dp[i]);
}
}
int maxx=0;
for (int i = 1; i <=n; ++i) {
maxx= max(dp[i],maxx);
}
cout<<maxx<<"\n";
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();//cout<<"\n";
}
return 0;
}
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
#define int long long
typedef long long LL;
typedef long long ll;
const int INF = 0x3f3f3f3f;
//const int inf = 1e18;
const int mod = 998244353;
//const int mod = 1e9 + 7;
int gcd(int a, int b) { return !b ? a : gcd(b, a % b); }
const int maxn = 1e6 + 10;
const int N = 5e5 + 100;
map<string, set<string>> ma;
multiset<int> se;
queue<int> qu;
vector<int> v;
int a[maxn];
int dp[maxn];
void solve() {
int n;
cin>>n;
int sum=-INF;
for (int i = 0; i < n; ++i) {
cin>>a[i];
dp[i]=a[i]+dp[i-1];
sum= max(dp[i],sum);
dp[i]=max(dp[i],0ll);
}
cout<<sum<<"\n";
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();//cout<<"\n";
}
return 0;
}