AtCoder Beginner Contest 216【C:简单思维】【D:双端队列+BFS 模拟】【E:优先队列+map 数学】【F:背包问题+优化】
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 #define int long long 5 #define pb push_back 6 7 int n; 8 vector<int> v; 9 signed main(){ 10 cin>>n; 11 while(n){ 12 if(n%2==0) 13 v.pb(1),n/=2; 14 else 15 v.pb(0),n--; 16 } 17 for(int i=v.size()-1;i>=0;i--) 18 if(!v[i]) cout<<"A";else cout<<"B"; 19 20 return 0; 21 } 22 /* 23 5 24 0 1 2 4 25 */
想了想,感觉没什么思维。直接用队列模拟就行
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 #define int long long 6 7 const int N = 5e5 + 100 ; 8 9 deque<int> q[N]; 10 queue<int> p; 11 int n,m,k; 12 vector<int> id[N]; 13 signed main(){ 14 cin>>n>>m; 15 for(int i=1;i<=m;i++){ 16 cin>>k; 17 for(int j=1;j<=k;j++){ 18 int x; 19 cin>>x; 20 q[i].push_back(x); 21 } 22 } 23 for(int i=1;i<=m;i++){ 24 if(q[i].size()<=0){ 25 continue; 26 } 27 id[q[i].front()].push_back(i); 28 if(id[q[i].front()].size()<=1){ 29 continue; 30 }else{ 31 p.push(q[i].front()); 32 while(!p.empty()){ 33 int tot=p.front(); 34 p.pop(); 35 if(id[tot].size()==2){ 36 int idx=id[tot][0]; 37 q[idx].pop_front(); 38 if(q[idx].size()>0){ 39 id[q[idx].front()].push_back(idx); 40 p.push(q[idx].front()); 41 } 42 idx=id[tot][1]; 43 q[idx].pop_front(); 44 if(q[idx].size()>0){ 45 id[q[idx].front()].push_back(idx); 46 p.push(q[idx].front()); 47 } 48 id[tot].clear(); 49 } 50 } 51 } 52 } 53 int F=1; 54 for(int i=1;i<=m;i++){ 55 if(q[i].size()){ 56 F=0; 57 break; 58 } 59 } 60 if(F) cout<<"Yes";else cout<<"No"; 61 return 0; 62 }
思路:优先队列模拟即可。剩下得就交给数学啦
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 const int N = 5e5 + 100 ; 5 int arr[N],n,k; 6 map<int,int> mp; 7 priority_queue<int> q; 8 signed main(){ 9 cin>>n>>k; 10 for(int i=1;i<=n;i++){ 11 cin>>arr[i]; 12 if(mp[arr[i]]){ 13 mp[arr[i]]++; 14 }else{ 15 q.push(arr[i]); 16 mp[arr[i]]++; 17 } 18 } 19 int ans=0; 20 while(q.size()){ 21 int num=q.top(); 22 q.pop(); 23 if(q.size()){ 24 int tmp=q.top(); 25 int sum=(num-tmp)*mp[num]; 26 if(sum<=k){ 27 ans+=((((num+tmp+1))*(num-tmp))/2)*(mp[num]); 28 // cout<<"1 "<<ans<<" "<<sum<<endl; 29 mp[tmp]=mp[tmp]+mp[num]; 30 mp[num]=0; 31 k-=sum; 32 }else{ 33 34 ans+=(((num+(num-(k/mp[num]-1)))*(k/mp[num]))/2)*mp[num]+(num-k/mp[num])*(k%mp[num]); 35 // cout<<"2 "<<ans<<endl; 36 break; 37 } 38 }else{ 39 if(mp[num]*num<=k){ 40 ans+=mp[num]*(num*(num+1)/2); 41 42 // cout<<"3 "<<ans<<endl; 43 }else{ 44 ans+=(((num+(num-(k/mp[num]-1)))*(k/mp[num]))/2)*mp[num]+(num-k/mp[num])*(k%mp[num]); 45 break; 46 // cout<<"4 "<<ans<<endl; 47 } 48 49 } 50 } 51 cout<<ans<<endl; 52 return 0; 53 } 54 /* 55 56 */
题意:给你n物品,每个物品有a和b两个属性。你现在要挑选出一个集合S。
使得max ai >= sum(bi) {i ∈ S} 问有多少种挑选方案。S不为空
思路: 将Ai排序,可以先将每个Ai想象成一个体积为Ai的背包,找前i个Bi能放下的数量。 接着我们考虑背包DP方程:DP[i][j]:表示当前已经处理到第i为,且第Bi为必拿,那么J=A[i]-B[i],J为体积。这样的话就可以写出一个O(N^3)的算法。但是过不了QAQ我们要进行优化,化到O(N^2) 学习一下优化:我们将J从原先不小于(A[i]-B[i])扩展为5000,向后优化。(秒啊!!)这样就能直接统计!
O(N^3)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 #define int long long 6 7 const int N = 6e3+100 , mod = 998244353; 8 struct str{ 9 int a,b; 10 }st[N]; 11 bool cmp(str A,str B){ 12 if(A.a!=B.a){ 13 return A.a<B.a; 14 }else{ 15 return A.b<B.b; 16 } 17 } 18 int qpow(int a,int b){ 19 int s=1; 20 while(b){ 21 if(b%2){ 22 s=(s*a)%mod; 23 } 24 a=(a*a)%mod; 25 b/=2; 26 } 27 return s; 28 } 29 int dp[N]; 30 int n; 31 int w[N]; 32 // 33 signed main(){ 34 int ans=0; 35 cin>>n; 36 for(int i=1;i<=n;i++) cin>>st[i].a; 37 for(int i=1;i<=n;i++) cin>>st[i].b; 38 sort(st+1,st+1+n,cmp); 39 for(int i=1;i<=n;i++){ 40 int val=st[i].a-st[i].b; 41 42 memset(dp,0,sizeof(dp)); 43 dp[0]=1; 44 for(int j=1;j<i;j++){ 45 for(int k=val;k>=st[j].b;k--){ 46 dp[k]=(dp[k]+dp[k-st[j].b])%mod; 47 } 48 } 49 for(int j=0;j<=val;j++) 50 ans=(ans+dp[j])%mod; 51 } 52 cout<<ans; 53 return 0; 54 }
O(N^2)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 #define int long long 6 7 const int N = 6e3+100 , mod = 998244353; 8 struct str{ 9 int a,b; 10 }st[N]; 11 bool cmp(str A,str B){ 12 if(A.a!=B.a){ 13 return A.a<B.a; 14 }else{ 15 return A.b<B.b; 16 } 17 } 18 int qpow(int a,int b){ 19 int s=1; 20 while(b){ 21 if(b%2){ 22 s=(s*a)%mod; 23 } 24 a=(a*a)%mod; 25 b/=2; 26 } 27 return s; 28 } 29 int dp[N]; 30 int n; 31 int w[N]; 32 signed main(){ 33 int ans=0; 34 cin>>n; 35 36 for(int i=1;i<=n;i++) cin>>st[i].a; 37 for(int i=1;i<=n;i++) cin>>st[i].b; 38 sort(st+1,st+1+n,cmp); 39 dp[0]=1; 40 for(int i=1;i<=n;i++){ 41 int val=st[i].a-st[i].b; 42 for(int j=0;j<=val;j++) 43 ans=(ans+dp[j])%mod; 44 for(int j=5100;j>=st[i].b;j--){ 45 dp[j]=(dp[j]+dp[j-st[i].b])%mod; 46 } 47 } 48 cout<<ans; 49 return 0; 50 }
· ASP.NET Core - 日志记录系统(二)
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 终于决定:把自己家的能源管理系统开源了!
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(一):从.NET IoT入
· C#实现 Winform 程序在系统托盘显示图标 & 开机自启动
· ASP.NET Core - 日志记录系统(二)
· 实现windows下简单的自动化窗口管理
2019-10-09 Maratona Brasileira de Popcorn( 二分答案+暴力 )