A. Coins
题解:签到
代码
#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
LL n,s, ans = 0;
cin>>n>>s;
ans = s / n;
if(s % n == 0) {
cout<< ans <<endl;
}else {
cout<< ans + 1 << endl;
}
return 0;
}
B. Views Matter
题解:很容易发现,为了保持俯视图不变,每列最少要留一个,为了保持侧视图不变,从 1 1 1到 m a x H maxH maxH每行最小要留一个。那么我们就排个序,贪心的去构造,如果当前 a [ i ] > = l a s t a[i] >= last a[i]>=last,那么本次就可以放到 l a s t + 1 last+1 last+1的高度,否则随便放一个位置即可。
#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
int a[100100];
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
int n,m,x,max1 = 0,cnt = 0;
LL sum = 0;
cin>>n>>m;
for(int i = 0; i < n; ++i) {
scanf("%d",&x);
max1 = max(max1,x);
sum += x - 1;
a[i] = x;
}
sort(a,a+n);
int last = 0;
for(int i = 0; i < n; ++i) {
if(i == n - 1 && a[i] > last) {
last = a[i] - last;
sum = sum - last + 1;
break;
}else if(i == n -1){
break;
}
if(a[i] > last) last++;
}
cout<<sum<<endl;
return 0;
}
C. Multiplicity
题解:首先肯定可以想到
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示从
a
1
,
a
2
,
a
3
,
.
.
.
a
i
a_1,a_2,a_3,...a_i
a1,a2,a3,...ai中选取长度为
j
j
j的好子序列的方案数。那么就有
d
p
[
i
]
[
j
]
=
{
d
p
[
i
−
1
]
[
j
]
+
d
p
[
i
−
1
]
[
j
−
1
]
i
f
(
a
[
i
]
%
j
=
=
0
)
d
p
[
i
−
1
]
[
j
]
e
l
s
e
dp[i][j] = \begin{cases}dp[i-1][j] + dp[i - 1][j-1]&\text{$if(a[i] \% j == 0)$}\\\\ dp[i -1][j]&\text{$else$}\end{cases}
dp[i][j]=⎩⎪⎨⎪⎧dp[i−1][j]+dp[i−1][j−1]dp[i−1][j]if(a[i]%j==0)else
但是发现时间复杂度是不允许的,所以我们再看会发现
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]只会从两个变量
d
p
[
i
−
1
]
[
j
]
dp[i-1][j]
dp[i−1][j]和
d
p
[
i
−
1
]
[
j
−
1
]
dp[i-1][j-1]
dp[i−1][j−1]转移过来,并且dp[j]只会当
a
[
i
]
%
j
=
=
0
a[i] \% j == 0
a[i]%j==0时才会被更新。因此就可以只保留一维即可。然后可以在
x
\sqrt{x}
x的时间内找出
a
[
i
]
a[i]
a[i]的因子。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 100100, mod = 1e9+7;
int a[N], dp[N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
int n;
cin>>n;
for(int i = 1; i <= n; ++i) {
scanf("%d",&a[i]);
}
for(int i = n; i >= 1; --i) {
for(int j = 1; j * j <= a[i]; ++j) {
if(a[i] % j == 0) {
if(j <= n)
dp[j] = dp[j + 1] + dp[j] + 1, dp[j] %= mod;
if(j * j != a[i] && a[i] / j <= n)
dp[a[i] / j] = dp[a[i] / j] + dp[a[i] / j + 1] + 1, dp[a[i] / j] %= mod;
}
}
}
printf("%d\n",dp[1]);
return 0;
}