T1:
简单模拟,注意初始化。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,ans;char a[100000],b[100000],s[10005];
int main() {
scanf("%d",&n);
scanf("%s",a+1);
scanf("%s",b+1);
scanf("%d",&m);
int l,r,c;
for(int i=1; i<=m; i++) {
scanf("%d%d%d",&l,&r,&c);
if(l>r)swap(l,r);
for(int j=l; j<=r; j++) {
int k=j-l+1+c;
k=k%(r-l+1);//显而易见的公式。。。
if(k==0)s[r]=a[j];
s[l-1+k]=a[j];
}
for(int j=l; j<=r; j++) {
a[j]=s[j];
}
memset(s,0,sizeof(s));
}
for(int i=1; i<=n; i++) {
if(a[i]==b[i])ans++;
}
cout<<ans;
}
没多少好说的。。。。
T2:
额,思路是贪心,就是每次都算一下在当前的最大高度保留时拆的符合条件的最小费用再与答案比较。但如果只是一开始按费用排完序然后每次都从低费用的开始取比最大高度矮的显然会TLE,所以考虑从上一个最大高度的费用稍做修改,将拆掉的高度比现在高的加回来,再取其他的。这样就需要一个优先队列来维护高度。
比较懒。。。。。待会再回来填坑。。。。。
T3:
又是贪心。。。。
明显每次都用除草机来除面积最大的是最优的,这样其他的每次就减一个单位的就好了,又是开个优先队列,取队头即最大的那个用除草机。其他减一的就当做所有一起减只有用除草机的加一,到判是否出队时与时间做比较,减了时间次一,小于时间直接出队。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int n,m,tot=0,a,ans=0;;
priority_queue<int> q;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a);
if(a!=0)q.push(a);
}
while(!q.empty()){
int k=q.top();q.pop();
if(k<ans)break;
else ans++;
q.push(max(k-m+1,0));
}
cout<<ans;
}
T4:
动归,
转移
(1)只有第i只猴子爬到第j棵树上
(2)除了第i只猴子外还有别的猴子爬到第j棵树上
f[i][j]=min{f[i-1][j-1],f[i-1][j]}+abs(a[i]-b[j])
时间复杂度为O(n^2)
特别注意要有滚动数组,否则会超空间、
#include <iostream>
using namespace std;
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
const int N=5005;
int n,m;
int x[N],y[N];
long long f[2][N];
int main(){
int i,j;
scanf("%d",&n);for(i=1;i<=n;i++) scanf("%d",&x[i]);
scanf("%d",&m);for(i=1;i<=m;i++) scanf("%d",&y[i]);;
sort(x+1,x+n+1);//排序
sort(y+1,y+m+1);//排序
memset(f,0x7f,sizeof(f));
f[1][1]=abs(x[1]-y[1]);
for(i=2;i<=n;i++)
for(j=1;j<=m;j++)
f[i&1][j]=min(f[i-1&1][j-1],f[i-1&1][j])+(long long)abs(x[i]-y[j]);
cout<<f[n&1][m]<<endl;
return 0;
}