Drop Voicing
题意:给你一个序列,可以执行两种操作,第一种操作就是将序列的倒数第二个数移到最前面,第二种操作就是将序列的最后一个数移到最前面。要求问至少要进行几次第二种操作才能使得整个序列是一个升序的排列。
思路:我们先观察两种操作的区别,我们发现,对于第一种操作,就是可以改变序列的LIS(即最长升序序列的长度),而第二种操作就是可以改变任意一个数到任意的位置。因此,最终的答案就是先把序列看成一个环,从序列中选择一个起点,然后看序列的长度减去LIS的长度的最小值就是我们要求的答案了。
代码:
#include<bits/stdc++.h> using namespace std; int dp[10010]; int a[10010]; int main(){ int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) a[n+i]=a[i]; int res=1e9+7; int ans; for(int i=1;i<=n;i++){ memset(dp,0,sizeof(dp)); for(int j=i;j<=n+i-1;j++){ ans=-1; dp[j]=1; for(int k=i;k<j;k++){ if(a[j]>=a[k]&&(dp[k]+1)>dp[j]) dp[j]=dp[k]+1; } ans=max(ans,dp[j]); } // cout<<ans<<endl; res=min(res,n-ans); } cout<<res<<endl; return 0; }
DPS
题意:
根据这个公式,对输入的d求出对应的s,然后用图像进行表示出来即可。同时再最大值的那个s对应位置上标上星号。
思路:简单模拟,注意可能有多个最大值即可。
代码:
#include<iostream> #include<cmath> using namespace std; typedef long long ll; ll d[120]; int main(){ int n; cin>>n; ll mx=-1; for(int i=0;i<n;i++){ cin>>d[i]; mx=max(mx,d[i]); } for(int i=0;i<n;i++){ ll temp=50*d[i]; ll s=temp/mx; if(temp%mx!=0) s++; cout<<"+"; for(int j=0;j<s;j++) cout<<'-'; cout<<"+"<<endl; cout<<"|"; for(int j=0;j<s;j++){ if(j==s-1&&d[i]==mx) cout<<'*'; else cout<<' '; } cout<<"|"<<d[i]<<endl; cout<<"+"; for(int j=0;j<s;j++) cout<<'-'; cout<<"+"<<endl; } return 0; }
Hard Math Problem
题意:一个无穷大的网格,每个格子可以是1,2,或者3,到那时每个1旁边一定要有一个2或者3,使得机器占比最大时多少?
思路:很显然最终的答案只有一种情况,这题比赛的时候我是直接猜的,没想到欧皇附体,没几下就猜中了。就是2和3交错使用一个。如:2 1 3 1 2 1 3 1....最后,我们的2和3的地位是相等的,2和3的数量加起来就有1的数量的一半,那么1的数量就是总数量的2/3,最后输出即可。
代码:
#include<iostream> #include<cmath> using namespace std; int main(){ double ans=0.666667; printf("%.6lf\n",ans); return 0; }