牛客網36-A,B題解
A.Rabbit的字串
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld
題目描述
Rabbit得到了一個字串,她的好朋友xxx可以給這個字串施加一次魔法。
魔法可以選擇字串的任一位置,並將該位置後面的所有字元水平拼接到串首。
例如:對於字串abcde,可以通過施加魔法得到cdeab。
如果xxx通過施加魔法將字串的字典序變得嚴格比之前的小,那麼他將拿走這一字串。
Rabbit想知道自己的字串會不會被xxx拿走。
輸入描述:
第一行一個整數n,表示字串的長度。 接下來一行一個長度為n的只由小寫字母組成的字串。
輸出描述:
如果Rabbit的字串會被xxx拿走,輸出“YES”。
否則輸出“NO”。
(不輸出引號)
示例1
輸入
5
cdeab
輸出
YES
說明
xxx可以把e之後的部分“ab”放到串首,得到abcde,字典序比cdeab小,故將拿走字串。
示例2
輸入
5
abcde
輸出
NO
備註:
1≤n≤100000
字典序的說明:https://en.wikipedia.org/wiki/Alphabetical_order
思路:此題的想法是我的i想法是直接找後邊是否存在比它小的,但是我們要考慮相等的時候,比如,abcab,這樣也可以,我們可以試著將相等的複製到一個新的串中,然後拼接一下,但是我是水了一下他的資料
程式碼:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; char str[100005]; int main() { int n; cin>>n; scanf("%s",str); int flag=0; for(int t=1;t<n;t++) { if(str[t]<str[0]) { flag=1; cout<<"YES"<<endl; return 0; } } char str1[100005]; for(int t=1;t<n;t++) { if(str[t]==str[0]&&str[t+1]<str[1]&&str[t+2]<str[2]) { flag=1; cout<<"YES"<<endl; return 0; } } if(flag==0) { cout<<"NO"<<endl; } return 0; return 0; }
B.Rabbit的工作(1)
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld
題目描述
Rabbit大學畢業後找到了一份實習工作,如果實習通過她就轉正了。
實習期共有N天,其中有幾天公司集體放假,Rabbit不用上班,剩下時間她可以選擇工作或者休息。Rabbit工作總是越來越累,可是每當她休息時,她就重新充滿了能量。簡而言之,Rabbit第一天工作時這一天會消耗體力1,連續第二天工作時這一天會消耗體力2,連續第三題工作時這一天會消耗體力3,以此類推......每當她休息後,工作的第一天又會消耗體力1。
為了讓boss滿意,Rabbit想工作儘量多的天數,但是懶惰的Rabbit又想讓自己的總體力消耗不超過K。
輸入描述:
第一行兩個整數N,K。 第二行一個長度為N的01字串。如果第i個字元為‘1’,表示這一天Rabbit可以選擇工作或者休息,否則這一天Rabbit放假。
輸出描述:
輸出Rabbit最多能工作的天數。
示例1
輸入
4 2 1011
輸出
2
說明
第三天和第四天裡面休息一天即可,總體力消耗為2
備註:
1<=N<=400 1<=K<=N∗(N+1)/2
思路:可以用dp來做
設d[ i ][ j ][ p ]為在 i 天時,一共工作了 j 天,且連續工作了 p 天直到第 i 天時花費的最小體力。那麼轉移方程很簡單:
如果第 i 天我不工作,那麼對於所有的合法的 p,d[ i ][ j ][ 0 ]=max( d[ i-1 ][ j ][ p ] ),如果我第 i 天工作,那麼對於所有合法的 j 和 p,d[ i ][ j ][ p ]=d[ i-1 ][ j-1 ][ p-1 ]+p,然後對於所有的d[ i ][ j ][ p ]<=k,取一個最大的 j 當答案即可。
程式碼:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int d[405][405][35],n,k,ans;
char s[160000];
int main()
{
cin>>n>>k>>s+1;
memset(d,-1,sizeof(d));
d[0][0][0]=0;
for(int i=1;i<=n;i++)
{
if(s[i]=='1')
{
for(int j=1;j<=n;j++)
for(int p=1;p*(p+1)/2<=n;p++)
if(d[i-1][j-1][p-1]!=-1)
{
d[i][j][p]=d[i-1][j-1][p-1]+p;
if(d[i][j][p]<=k)
ans=max(ans,j);
}
}
for(int j=0;j<=n;j++)
for(int p=0;p*(p+1)/2<=n;p++)
if(d[i-1][j][p]!=-1)
{
if(d[i][j][0]==-1)d[i][j][0]=d[i-1][j][p];
else
d[i][j][0]=min(d[i-1][j][p],d[i][j][0]);
if(d[i][j][0]<=k)
ans=max(ans,j);
}
}
cout<<ans;
}