预期 | 一测 | ||
a | 100 | 20 | -80 |
b | 100 | 100 | 0 |
c | 100 | 100 | 0 |
d | 100 | 88 | -12 |
e | 0 | 0 | 0 |
总分· | 400 | 308 | -92 |
问题 A: 零件分组(stick)
分析题意可将题转化为求最长不上升子序列。
#include<bits/stdc++.h>
using namespace std;
#define N 1010
struct node{
int l,w;
}t[N];
bool operator < (node x,node y){
return x.l<y.l || x.l==y.l && x.w<y.w;
}
int n;
int f[N],ans;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d%d",&t[i].l,&t[i].w);
}
sort(t+1,t+n+1);
for(int i=1;i<=n;i++){
f[i]=1;
for(int j=1;j<i;++j){
if(t[j].w>t[i].w){
f[i]=max(f[i],f[j]+1);
}
}
ans=max(ans,f[i]);
}
printf("%d",ans);
return 0;
}
问题 C: 最优贸易
先以 1 为起点,SPFA一遍求出一个数组 D ,表示表示从节点 1 到 当前节点的路径中,能经过的最小点权值,由于不满足Dijkstra的贪心性质,需要选择SPFA算法,同理再以 n 为起点,求最大值数组 F 然后遍历所有的 F-D 就行了。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+6,M=1e6+6;
int n,m,tot,val[N],ans;
int h[N],to[M],nxt[M],d[N];
int fh[N],fto[M],fnxt[M],f[N];
priority_queue<pair<int,int> >q,fq;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",val+i);
for(int i=1;i<=m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
to[++tot]=y;nxt[tot]=h[x];h[x]=tot;
fto[tot]=x;fnxt[tot]=fh[y];fh[y]=tot;
if(z==2){
to[++tot]=x;nxt[tot]=h[y];h[y]=tot;
fto[tot]=y;fnxt[tot]=fh[x];fh[x]=tot;
}
}
memset(d,0x3f,sizeof(d));
d[1]=val[1];
q.push(make_pair(-d[1],1));
while(q.size()){
int x=q.top().second;
q.pop();
for(int i=h[x];i;i=nxt[i]){
int y=to[i];
if(d[y]>d[x]){
d[y]=d[x];
d[y]=min(d[y],val[y]);
q.push(make_pair(-d[y],y));
}
}
}
memset(f,0xcf,sizeof(f));
f[n]=val[n];
fq.push(make_pair(f[n],n));
while(fq.size()){
int x=fq.top().second;
fq.pop();
for(int i=fh[x];i;i=fnxt[i]){
int y=fto[i];
if(f[y]<f[x]){
f[y]=f[x];
f[y]=max(f[y],val[y]);
fq.push(make_pair(f[y],y));
}
}
}
for(int i=1;i<=n;i++) ans=max(ans,f[i]-d[i]);
cout<<ans;
return 0;
}
问题 D: Radio Transmission
由于KMP算法的性质,next数组不会把第一个循环节匹配进去,也就是n-next[n]就是答案。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define N 1000010
char a[N];
int nxt[N],n,b=131,ans=INT_MAX;
int main(){
scanf("%d",&n);
scanf("%s",a+1);
for(int i=2,j=0;i<=n;i++){
while(j && a[i]!=a[j+1]) j=nxt[j];
if(a[i]==a[j+1]) j++;
nxt[i]=j;
}
printf("%d",n-nxt[n]);
return 0;
}
/*
8
cabcabca
5
abaab
*/