周练1(一维线性dp

最长上升子序列

基础dp 状态转移方dp[i]=max(dp[i],dp[j]+1),j<i&&A[j]<A[i]

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int A[1007];
 5 int dp[1007]={0};
 6 int main()
 7 {
 8     int n,i,j,k;
 9     cin>>n;
10     for(i=1;i<=n;++i) cin>>A[i];
11     for(i=1;i<=n;++i)
12     {
13         for(j=1;j<i;++j)
14         {
15             if(A[j]<A[i]) dp[i]=max(dp[i],dp[j]+1);
16         } 
17     }
18     int ans=-1;
19     for(i=1;i<=n;++i)  ans=max(ans,dp[i]);
20     cout<<ans+1<<endl;
21     return 0;
22 }
View Code

B

一维线性dp

思路:兔子所用时间 T=L/VR. 对于乌龟,可以把每个充电桩近似看成终点,计算乌龟到每个充电桩的最短时间,可以推出到终点的最短时间。 设 j<i 且 j到i的最短时间为time,lx 为j到i的距离 则 lx<=C:time=lx/VT1;  lx>C:time=C/VT1+(lx-C)/VT2;

状态转移方程 dp[i]=min(dp[i],dp[j]+time)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int inf=0x3f3f3f3f;
 5 double A[1007];
 6 double dp[1007]={0};
 7 int main()
 8 {
 9     int n,i,j,k;
10     double L,N,C,VR,VT1,VT2,T;
11     while(cin>>L)
12     {
13     cin>>n>>C>>T;
14     cin>>VR>>VT1>>VT2;
15     for(i=1;i<=n;++i) cin>>A[i];
16     double fx=L/VR; 
17     A[n+1]=L; A[0]=0;
18     for(i=1;i<=n+1;++i)
19     {
20         dp[i]=inf; dp[0]=0;
21         for(j=0;j<i;++j)
22         {
23             double time=0;
24             double l=A[i]-A[j];
25             if(l<=C)
26             {
27                 time=time+l/VT1;
28             }
29             else {
30                 time=time+C/VT1+(l-C)/VT2;
31             }
32             if(j) time+=T;
33             dp[i]=min(dp[i],dp[j]+time);
34         }
35     }
36 //    printf("%.2f  %.2f\n",fx,dp[n+1]);
37     if(dp[n+1]<fx) printf("What a pity rabbit!\n");
38     else printf("Good job,rabbit!\n");    
39     }
40     
41     return 0; 
42 }
View Code

C

签到题

0-向左跳的距离+向右跳的距离

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int A[1007];
 5 int main()
 6 {
 7     ll x,y,z,t;
 8     cin>>t;
 9     while(t--)
10     {
11         ll ans=0;
12         cin>>x>>y>>z;
13         ans=ans-y*(z/2)+x*(z-z/2);
14         cout<<ans<<endl;
15     }
16     return 0;
17 }
View Code

D

贪心

每次遇到 1 0 1 这种情况变为 1 0 0 即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int A[1007];
 5 int main()
 6 {
 7     ll n,i,j,k,t;
 8     ll x,y,z;
 9     cin>>n;
10     for(i=1;i<=n;++i)
11     {
12         cin>>A[i];
13     }
14     int ans=0;
15     for(i=2;i<n;++i)
16     {
17         if(A[i]==0&&A[i-1]==1&&A[i+1]==1)
18         {
19             ans++;A[i+1]=0;
20             //cout<<i<<endl;
21         }
22     }
23     cout<<ans<<endl;
24     return 0;
25 }
View Code

E

思维 枚举

先求出数组总和值sum,枚举数组中每一个数x,将其减去 sum-=x; 判断一下sum/2 数组中剩下的数中是否存在,若存在,将数x存到另一个数组里。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int qs=2e5+7;
 5 int A[qs];
 6 int B[qs];
 7 map<int,int> mp;
 8 int main()
 9 {
10     ll n,i,j,k,t,x;
11     cin>>n;
12     ll sum=0;
13     for(i=1;i<=n;++i)
14     {
15         cin>>A[i]; sum+=A[i]; mp[A[i]]++;
16     } 
17     int ans=0;
18     for(i=1;i<=n;++i)
19     {
20         mp[A[i]]--;
21         double x=(double)(sum-A[i])/2;
22         if(x==(int)x&&mp[(int)x]>0) {
23             B[ans]=i;ans++; 
24         }
25         mp[A[i]]++;
26     }
27     cout<<ans<<endl;
28     for(i=0;i<ans;++i)
29     {
30         if(i==ans-1) printf("%d\n",B[i]);
31         else printf("%d ",B[i]);
32     }
33     return 0;
34 }
View Code

F

二分

思路:通过求重复次数x,在重复x中找到一个序列 L,若L的长度大于等于k,即满足要求。则二分求解重复次数x即可。

// 自己做的时候没想到二分emmm....

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int qs=2e5+7;
 5 map<int,int> mp;
 6 vector<int> v,c;
 7 int ck(int mid)
 8 {
 9     c.clear();
10     for(int i=0;i<v.size();++i)
11     {
12         int num=mp[v[i]]/mid;
13         for(int j=0;j<num;++j) c.push_back(v[i]);
14     }
15     return c.size(); 
16 }
17 int n,m;
18 int main()
19 {
20     int i,j,k,x,y;
21     cin>>n>>m;
22     int l,r;
23     y=-1;
24     for(i=1;i<=n;++i)
25     {
26         cin>>x;
27         if(!mp[x]) { mp[x]=0;
28             v.push_back(x);
29         }
30         mp[x]++; y=max(mp[x],y);
31     }
32     l=1;r=y;    
33     int ans=0;
34     while(l<=r)
35     {
36         int mid=(l+r)/2;
37         if(ck(mid)>=m)
38         {
39             l=mid+1; ans=mid;
40         }
41         else r=mid-1;
42     }
43     int xx=ck(ans);
44     for(i=0;i<m;++i)
45     {
46         if(i==m-1) printf("%d\n",c[i]);
47         else printf("%d ",c[i]);
48     }
49     return 0;
50 }
View Code

猜你喜欢

转载自www.cnblogs.com/Suki-Sugar/p/12694091.html