D. Stressful Training 题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有n台电脑,每台电脑都有初始电量ai,也有一个耗电量bi,意即每1s耗电多少,现在你有一个充电器,它每s可以给一台电脑充x的点亮. 问x最少为多少,可以让所有电脑直至k时刻,点亮都不小于0. 题解: 我们考虑贪心,先给最需要充电的电脑充电,然后二分答案x去检验.大概思路就是这样吧...但是实现起来还是有点困难. 首先处理出每个电脑最晚需要充电的…
https://codeforces.com/contest/1132/problem/E 题意 有8种物品,重量是1~8,每种数量是\(cnt[i]\)(1e16),问容量为W(1e18)的背包最多能装多少重量 题解1 多重背包二进制拆分物品转换成01背包,用map来剪枝掉无用的状态 #include<bits/stdc++.h> #define ll long long using namespace std; map<ll,bool>f,g; ll a[10],W,s[100…
题意就是给出多个区间,要求去掉两个区间,使得剩下的区间覆盖范围最大. 当然比赛的时候还是没能做出来,不得不佩服大佬的各种姿势. 当时我想的是用线段树维护区间和,然后用单点判0,维护区间间断个数.然后打到一半,就发现想法有问题. 这道题正解就是简单的前缀和,或者DP. 我为了更加深入理解,两种方法都试了试. 前缀和版本: 由于题目给的范围是5000,明显支持N^2,于是我们枚举去掉的两个,刚好满足,那么要如何才能O(1)的得到答案? 我们其实可以这样,我们知道它的总覆盖的数目,这是非常容易求出的.…
A. Regular Bracket Sequence 题意:给出四种括号的数量 ((  )) ()  )( 问是否可以组成合法的序列(只能排序不能插在另外一个的中间) 思路: 条件一:一个或 n个)( 都可以组成 )()()( 这种结构 这只需要 一个((和一个))就可以合成合法的序列 条件二: (( 和))需要相等 ()本身就合法不用管 ude<bits/stdc++.h> #define FOR(i,f_start,f_end) for(int i=f_startl;i<=f_en…
非常经典的dp题,因为1至8的最大公约数是840,任何一个数的和中840的倍数都是可以放在一起算的, 所以我只需要统计840*8的值(每个数字(1-8)的sum%840的总和),剩下都是840的倍数 dp[i][j] 代表讨论了第i位并且每个数字取余为j的情况 #include <assert.h> #include <algorithm> #include <bitset> #include <climits> #include <cmath>…
#include<bits/stdc++.h>using namespace std;int st[1000007];int top;int s[1000007],t[1000007];int mx[4000007];int sum[4000007];int head[1000007],to[2000007],nex[2000007];int n,k;int a[10000077];int dfn;int tot;void pushup(int rt){    mx[rt]=max(mx[rt…
#include<bits/stdc++.h>typedef long long ll;const int inf=0x3f3f3f3f;using namespace std;char b[507];int dp[507][507];int main(){    memset(dp,0x3f,sizeof(dp));    int n;    scanf("%d",&n);    scanf("%s",b+1);    for(int i=1;…
#include<bits/stdc++.h>using namespace std;typedef long long ll;int n,k;ll a[200007],b[200007],s[200007];ll ans;int check(ll val){ memset(s,0,sizeof(s)); int num=k; for(int i=1;i<=n;i++){  if(!b[i])   continue;  s[min(a[i]/b[i]+1,1ll*(k+1))]++;//…
从低位到高位枚举,当前位没有就去高位找到有的将其一步步拆分,当前位多余的合并到更高一位 #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; ]; ],num[]; int main(){ ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int t; cin>>t; while(t--){ memset(sum,,si…
题意:给你一个字符串,每次可以调换现字符串的相邻两个字符,问最少操作多少次使得这个字符串等于其反转过来的字符串. 题解:先考虑字符串中没有相同字符的情况,那么我们每次将目前字符串的最后一个字符一直调换到前面就行,如果出现相同字符的话,先让最靠前的字符调换到对应位置一定是最优的.我们先记录原字符串中每个字符的位置,然后将字符串反转,根据反转后的字符位置弄一个新数组,注意相同字符一定要把小的位置放在前面,然后用树状数组求个逆序对即可. 代码: #define int long long int n;…