2017 Latin American Regional Contests
E - Enigma
记忆化搜索,水题。比赛时候没敢写,又觉得会超时(为什么要说又!),因为觉得暴搜接近10e1000,觉得就算是记忆化也优化不了。我依稀记得上次给学弟讲BFS里面也有个记忆化搜索也觉得会T没敢写(艹)。
从高位开始,利用大数取模的思路,vis【i】【j】记录 是否到达过该状态,并且此状态往后递归后有能不能找到答案。(i为第i位,j未前i位mod n后的余数,vis值为正数即来过,1为后面无解,2为后面有解)。递归结束时往前返回状态记录答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
int vis[1005][1005];
char ans[1005],s[1005];
int len,n;
int dfs(int loc,int lastremainder)
{
if(loc>=len){
return lastremainder==0?2:1;
}
if(vis[loc][lastremainder]){
return vis[loc][lastremainder];
}
if(s[loc]=='?'){
for(int i=!loc; i<=9; i++){
if(dfs(loc+1,(lastremainder*10+i)%n)==2){
ans[loc]+=i+'0';
return vis[loc][lastremainder]=2;
}
}
return vis[loc][lastremainder]=1;
}
else{
ans[loc]=s[loc];
if(dfs(loc+1,(lastremainder*10+(s[loc]-'0'))%n)==2){
return vis[loc][lastremainder]=2;
}
return vis[loc][lastremainder]=1;
}
}
int main(){
cin>>s>>n;
len=strlen(s);
if(dfs(0,0)==2)
cout<<ans<<endl;
else
puts("*");
}
/*
input
?294?? 17
output
129404
*/
F - Fundraising
比赛时候懵了,不知道怎么下手,听完是最大递增子序列权值和,就明白怎么做了。用第一维排序,第二维离散,拿第二维扔进树状数组里,对于每个数在树状数组里更新成比当前数小的区间里最大的权值和加本身后的最大值。树状数组维护区间最大值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
struct node{
int a,b;
ll c;
}f[100005];
bool cmp(node x,node y){
if(x.a==y.a){
return x.b>y.b;
}
return x.a<y.a;
}
bool cmp2(node x,node y){
return x.b<y.b;
}
bool cmp3(node x,node y){
return x.a<y.a;
}
map<pair<int,int>,int>mp;
ll tree[100005];
int num;
void add(ll x,ll y){
for(;x<=num;x+=x&-x) tree[x]=max(tree[x],y);
}
ll ask(ll x){
ll res=0;
for(;x>=1;x-=x&-x) res=max(tree[x],res);
return res;
}
int main(){
int n;
cin>>n;
mp.clear();
memset(tree,0,sizeof(tree));
int cnt=0,a,b,c,loc=0;
for(int i=0;i<n;++i){
cin>>a>>b>>c;
loc=mp[make_pair(a,b)];
if(loc){
f[loc].c+=c;
}
else{
f[++cnt].a=a;
f[cnt].b=b;
f[cnt].c=c;
mp[make_pair(a,b)]=cnt;
}
}
sort(f+1,f+cnt+1,cmp);
for(int i=1;i<=cnt;i++){
f[i].a=i;
}
sort(f+1,f+cnt+1,cmp2);
int la=-1;
num=0;
for(int i=1;i<=cnt;i++){
if(f[i].b!=la){
num++;
}
la=f[i].b;
f[i].b=num;
}
sort(f+1,f+cnt+1,cmp3);
for(int i=1;i<=cnt;i++)
{
add(f[i].b,ask(f[i].b-1)+f[i].c);
}
cout<<ask(num)<<endl;
}

浙公网安备 33010602011771号