Acwing 刷题4

AcWing 1212.地宫取宝

思路

动态规划,数组f[i][j][a][b]的含义为在i,j这个格子,已经取了a个物品,最大物品价值为b的方案的方案数。

题解

#include<bits/stdc++.h>
using namespace std;

const int N=55,mod=1e9+7;
int f[N][N][13][14];
int w[N][N];
int n,m,k,ans;		//数组f[i][j][a][b]的含义为在i,j这个格子,
//已经取了a个物品,最大物品价值为b的方案的方案数

int main()
{
	cin>>n>>m>>k;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
		{
			cin>>w[i][j];
			w[i][j]++; //物品价值统一+1
		}
	f[1][1][1][w[1][1]]=1; //初始化,取第一个物品的时候
	f[1][1][0][0]=1; //初始化,不取第一个物品的时候,最大价值为-1+1=0
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
		{
			if(i==1&&j==1) continue;
			for(int a=0; a<=k; a++)
				for(int b=0; b<=13; b++)
				{
					int &val=f[i][j][a][b]; //不取的情况,该格等于上一格加左一格
					val=(val+f[i-1][j][a][b])%mod;
					val=(val+f[i][j-1][a][b])%mod;
					if(a>0&&b==w[i][j])
					{
						for(int c=0; c<b; c++)
						{
							val=(val+f[i-1][j][a-1][c])%mod;
							val=(val+f[i][j-1][a-1][c])%mod;
						}
					}
				}
		}
	for(int i=0; i<=13; i++)
		ans=(ans+f[n][m][k][i])%mod;
	cout<<ans<<endl;
	return 0;
}

AcWing 1214.波动数列

思路

题解

#include<bits/stdc++.h>
using namespace std;

const int N=1010,mod=100000007;
int f[N][N];
int n,s,a,b; 

int getmod(int a,int b)
{
	return (a%b+b)%b;
}

int main()
{
	cin>>n>>s>>a>>b;
	f[0][0]=1;
	for(int i=1;i<n;i++)
		for(int j=0;j<n;j++)
			f[i][j]=(f[i-1][getmod(j-(n-i)*a,n)]+f[i-1][getmod(j+(n-i)*b,n)])%mod;
	cout<<f[n-1][getmod(s,n)]<<endl;
	return 0;
}

AcWing 1210.连号区间数

思路

题解

#include<bits/stdc++.h>
using namespace std;

const int N=10010;
int f[N],n,ans;

int main()
{
	cin>>n;
	for(int i=1; i<=n; i++)
		cin>>f[i];
	for(int i=1; i<=n; i++)
	{
		int ma=f[i];
		int mi=f[i];
		for(int j=i;j<=n;j++)
		{
			ma=max(ma,f[j]);
			mi=min(mi,f[j]);
			if(ma-mi==j-i) ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
}

AcWing 1236.递增三元组

思路

前缀和

题解

#include<bits/stdc++.h>
using namespace std;

const int N=100010;
int a[N],b[N],c[N],n;
long long ans;
int A[100010],C[100010];
long long s1[100010],s2[100010];

int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		A[a[i]]++;
	}
	for(int i=0;i<n;i++)
		cin>>b[i];
	for(int i=0;i<n;i++)
	{
		cin>>c[i];
		C[c[i]]++;
	}
	s1[0]=A[0];
	s2[0]=C[0];
	for(int i=1;i<=100000;i++)
	{
		s1[i]=s1[i-1]+A[i];
		s2[i]=s2[i-1]+C[i];
	}
	
	for(int i=0;i<n;i++)
		ans+=(s1[b[i]-1])*(s2[100000]-s2[b[i]]);

	cout<<ans<<endl;
	return 0;
}

AcWing 1245.特别数的和

思路

暴力不用说

题解

#include<bits/stdc++.h>
using namespace std;

const int N=10010;

int main()
{
	int n,x;
	long long ans=0;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int a,b;
		b=i;
		while(b>0)
		{
			int a=b%10;
			if(a==2||a==0||a==1||a==9)
			{
				ans+=i;
				break;
			}
			else b/=10;
		}
	}
	cout<<ans<<endl;
	return 0;
}

posted @ 2022-03-07 20:13  longwind7  阅读(36)  评论(0编辑  收藏  举报