文章目录
A - Grade Allocation
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ll t;
cin>>t;
while(t--){
ll n,m;
cin>>n>>m;
ll sum=0;
while(n--){
ll x;
cin>>x;
sum+=x;
}
cout<<min(m,sum)<<endl;
}
}
B - String Modification
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ll t;
cin>>t;
while(t--){
ll n,m;
cin>>n>>m;
ll sum=0;
while(n--){
ll x;
cin>>x;
sum+=x;
}
cout<<min(m,sum)<<endl;
}
}
C - Primitive Primes
对于模p,求两个多项式卷积的系数模p非零的位置。
不用真正的做卷积
fft算法会有精度问题。
将两个多项式从高次向低次遍历找最高的模p非0的位置,最后两位置相加即为答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
template <class T>
inline void scan_d(T &ret)
{
char c;
ret = 0;
while ((c = getchar()) < '0' || c > '9');
while (c >= '0' && c <= '9')
{
ret = ret * 10 + (c - '0'), c = getchar();
}
}
ll a[maxn];
ll b[maxn];
int main(){
ll n,m,p;
scan_d(n);
scan_d(m);
scan_d(p);
for(ll i=0;i<n;i++){
scan_d(a[i]);
a[i]%=p;
}
for(ll i=0;i<m;i++){
scan_d(b[i]);
b[i]%=p;
}
ll curn=n-1,curm=m-1;
while(a[curn]==0){
curn--;
}
while(b[curm]==0){
curm--;
}
cout<<curn+curm<<endl;
}
D - Nash Matrix
对于到本身的点,答案为X,以这些点为起点进行dfs
对于目的地为(-1,-1)的点,若周围存在目的地为(-1,-1)的点,则以该点位起点dfs
若最后所有点都遍历到,则为VALID
否则为INVALID
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e3+10;
const ll d[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
const char D[4]={'D','U','L','R'};
const char D2[4]={'U','D','R','L'};
pair<ll,ll>pr[maxn][maxn];
char ans[maxn][maxn];
ll n;
bool in(ll x,ll y){
return x>=1&&x<=n&&y>=1&&y<=n;
}
void dfs(ll x,ll y,ll X,ll Y){
for(ll i=0;i<4;i++){
ll curx=x+d[i][0],cury=y+d[i][1];
if(!in(curx,cury)||ans[curx][cury]!='@')
continue;
if(pr[curx][cury]==make_pair(X,Y)){
ans[curx][cury]=D[i];
dfs(curx,cury,X,Y);
}
}
}
int main(){
cin>>n;
for(ll i=1;i<=n;i++){
for(ll j=1;j<=n;j++){
scanf("%lld%lld",&pr[i][j].first,&pr[i][j].second);
}
}
for(ll i=1;i<=n;i++){
for(ll j=1;j<=n;j++){
if(pr[i][j]==make_pair(i,j)){
ans[i][j]='X';
}
else{
ans[i][j]='@';
}
}
}
for(ll i=1;i<=n;i++){
for(ll j=1;j<=n;j++){
if(ans[i][j]=='X'){
dfs(i,j,i,j);
}
else if(pr[i][j]==make_pair((ll)-1,(ll)-1)&&ans[i][j]=='@'){
for(ll k=0;k<4;k++){
ll x=i+d[k][0],y=j+d[k][1];
if(in(x,y)&&ans[x][y]=='@'&&pr[x][y]==make_pair((ll)-1,(ll)-1)){
ans[i][j]=D2[k];
dfs(i,j,-1,-1);
break;
}
}
}
}
}
bool flag=true;
for(ll i=1;i<=n;i++){
for(ll j=1;j<=n;j++){
if(ans[i][j]=='@'){
flag=false;
}
}
}
if(flag){
puts("VALID");
for(ll i=1;i<=n;i++){
for(ll j=1;j<=n;j++){
printf("%c",ans[i][j]);
}
printf("\n");
}
}
else{
puts("INVALID");
}
return 0;
}
E - Team Building
状压dp
dp[i][j]表示前i个人,在状态j下的最大值
将n个人从观众能力从高到地排序
先不考虑球员的能力,确定每个状态的初始值
再考虑球员的能力,进行dp
状态转移:
d
p
[
i
]
[
j
∣
1
<
<
k
]
=
m
a
x
(
d
p
[
i
]
[
j
∣
1
<
<
k
]
,
d
p
[
i
−
1
]
[
j
]
+
f
[
i
d
[
i
]
]
[
k
+
1
]
)
;
dp[i][j|1<<k]=max(dp[i][j|1<<k],dp[i-1][j]+f[id[i]][k+1]);
dp[i][j∣1<<k]=max(dp[i][j∣1<<k],dp[i−1][j]+f[id[i]][k+1]);
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e5+10;
ll a[maxn];
ll id[maxn];
ll f[maxn][8];
ll dp[maxn][1<<7];
int main(){
ll n,p,k;
cin>>n>>p>>k;
memset(dp,-1,sizeof(dp));
for(ll i=1;i<=n;i++){
scanf("%lld",&a[i]);
id[i]=i;
}
for(ll i=1;i<=n;i++){
for(ll j=1;j<=p;j++){
scanf("%lld",&f[i][j]);
}
}
sort(id+1,id+1+n,[](ll x,ll y){
return a[x]>a[y];});
dp[0][0]=0;
for(int i=1;i<=n;i++){
for(ll j=0;j<(1<<p);j++){
ll cnt=0;
for(ll k=0;k<p;k++){
if(j&(1<<k)){
cnt++;
}
}
if(dp[i-1][j]!=-1){
if(i-1-cnt>=k)
dp[i][j]=dp[i-1][j];
else
dp[i][j]=dp[i-1][j]+a[id[i]];
}
}
for(ll j=0;j<(1<<p);j++){
for(ll k=0;k<p;k++){
if(!(j&(1<<k))&&dp[i-1][j]!=-1){
dp[i][j|1<<k]=max(dp[i][j|1<<k],dp[i-1][j]+f[id[i]][k+1]);
}
}
}
}
cout<<dp[n][(1<<p)-1]<<endl;
}