Day3的题目也太难了哇
F.Mountain Scenes
做法:计数dp(我觉得是计数的。。。)
dpi,j:填充第i列,用的方块数量为j时的方案数dp_{i,j}:填充第i列,用的方块数量为j时的方案数dpi,j:填充第i列,用的方块数量为j时的方案数
当前位于第iii列,用到的方块数量是jjj,当前列高度为kkk,
转移方程:dpi,j+k+=dpi−1,jdp_{i,j+k}+=dp_{i-1,j}dpi,j+k+=dpi−1,j
emmm不过上述转移式不太明白,明白的是下一个:
dp[i][j]=∑k=0j≥kdp[i−1][j−k]dp[i][j]=\sum \limits_{k=0}^{j\ge k}dp[i-1][j-k]dp[i][j]=k=0∑j≥kdp[i−1][j−k]
欢迎dalao留言解释QAQ
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e2+2,mod=1e9+7;
int dp[maxn][maxn*maxn];
int n,w,h;
int main()
{
cin>>n>>w>>h;
dp[0][0]=1;
for(int i=1;i<=w;++i)
{
for(int j=0;j<=n;++j)
{
if(dp[i-1][j])
for(int k=0;k<=h;++k)
{
if(j+k>n) break;
{
dp[i][j+k]+=dp[i-1][j];
dp[i][j+k]%=mod;
//printf("dp[%d][%d]=%d\n",i,j+k,dp[i][j+k]);
}
}
}
}
long long ans=0;
for(int i=0;i<=n;++i) ans+=dp[w][i],ans%=mod;
int tmp=min(h+1,n/w+1);
ans-=tmp;
if(ans<0) ans+=mod;
cout<<ans<<endl;
}
I.Tourists
有一棵树,对于树的每个点,要走完所有这个点整倍数的点,花费是两点之间的经过的点的数量(包括起止点),即两点之间边数量+1,求整张图走完所有点的花费
因为这是一棵树,所以点与点之间仅有一条路径,lca板子题
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
vector<int>G[maxn];
int n;
int depth[maxn],father[maxn][40];
void dfs(int fa,int now)
{
for(int to:G[now])
{
if(to==fa) continue;
depth[to]=depth[now]+1;
father[to][0]=now;
dfs(now,to);
}
}
void bz()
{
for(int i=1;i<=30;++i)
{
for(int j=1;j<=n;++j)
{
father[j][i]=father[father[j][i-1]][i-1];
}
}
}
int LCA(int u,int v)
{
if(depth[u]>depth[v]) swap(u,v);
int flag=(u==1 && v==2);
if(flag)
{
int q=1;
}
int delt=depth[v]-depth[u];
int len=0;
for(int i=0;i<=30;++i) {
if ((1 << i) & delt) {
v = father[v][i], len += (1 << i);
int q=1;
}
}
if(u==v)
return len+1;
for(int i=30;i>=0;--i)
{
if(father[u][i]!=father[v][i])
{
len+=(1<<i)*2;
u=father[u][i];
v=father[v][i];
}
}
u=father[u][0];
return len+3;
}
int main()
{
//freopen("in.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<n;++i)
{
int a,b;scanf("%d%d",&a,&b);
G[a].push_back(b);
G[b].push_back(a);
}
dfs(-1,1);
bz();
long long ans=0;
for(int i=1;i<=n/2;++i)
{
for(int j=2*i;j<=n;j+=i)
{
ans+=LCA(i,j);
//printf("%d to %d is %d\n",i,j,LCA(i,j));
}
}
cout<<ans<<endl;
}