C
题意 :给你n个菜的ti,每个菜都可以在任意时间T上,每个时间都只能用一次,每个菜都会产生一个不满意值|T-ti|,让你求最小的总不满意值
很明显可以用dp做,不过我比赛时把他想的太简单了,我只想去每个菜直接去找离他最近的时间,用过的时间就跳过,这样是肯定不对的
正确思路应该是去用dp【i】【j】表示前i个菜用前j个时间,每次比较新的菜用新的时间是否可以更快
#include<bits/stdc++.h>
using namespace std;
int c,n,i,t,a[222],dp[222][444],j,k;
int main(){
cin>>t;
while(t--){
cin>>n;
for(i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(i=1;i<=2*n;i++) dp[0][i]=0;
for(j=1;j<=n;j++)
for(i=j;i<=2*n;i++){
x=1e8;
for(k=j;k<=i;k++)
if(x>abs(k-a[j])+dp[j-1][k-1])
x=abs(k-a[j])+dp[j-1][k-1];
dp[j][i]=x;
}
cout<<dp[n][2*n]<<"\n";
}
}
D
题意:给你一段序列让你建一个树,要求是,比前一个结点大就放在同层前一个结点后面,比前一个小就要放到下一层或者上一层的下一个结点
实际上是很简单的,每加入一个新结点只需要考虑和前面结点的大小关系和是否需要到下一层,
#include<iostream>
using namespace std;
int main(){
int n,m;
int x,y,z;
int i,j;
int t;
int a[100005];
cin>>t;
while(t--){
cin>>n;
for(i=1;i<=n;i++){
cin>>a[i];
}
int d=1;
x=a[2]; y=1; z=1; g=1;
for(i=3;i<=n;i++){
if(a[i]>x) {
x=a[i];
g++;
}
else{
y++;
if(y>z) {
d++;
z=g;
}
x=a[i];
}
}
cout<<d<<endl;
}
}