B. Digital root
题意:
题目定义了x的digital root是S(x)。S(5)=5,S(38)=S(3+8=11)=S(1+1+2)=2.
有n个询问,每次询问给出ki和xi,要你求出digital root为xi的整数中,第k大的是什么。
题解:
观察可以发现,x的digital S(x) 在模9下同余。也就是x mod 9 = S(x).发现这一点以后答案就很显然了。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 6 using namespace std; 7 typedef long long LL; 8 typedef unsigned long long ull; 9 int n,x; 10 LL k; 11 int main(){ 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++){ 14 scanf("%I64d%d",&k,&x); 15 ull res=x+(k-1)*9; 16 printf("%I64u\n",res); 17 } 18 return 0; 19 }
C. Brutality
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <queue> 6 using namespace std; 7 typedef long long LL; 8 const int maxn=2e5+100; 9 int n,k; 10 int a[maxn]; 11 char s[maxn]; 12 13 int main(){ 14 scanf("%d%d",&n,&k); 15 for(int i=1;i<=n;i++){ 16 scanf("%d",&a[i]); 17 } 18 scanf("%s",s+1); 19 priority_queue<int,vector<int>,greater<int> >q; 20 LL ans=0; 21 LL sum=0; 22 int num=0; 23 for(int i=1;i<=n;i++){ 24 if(s[i]==s[i-1]){ 25 num++; 26 sum+=a[i]; 27 q.push(a[i]); 28 if(num>k){ 29 sum-=q.top(); 30 // printf("!%d\n",q.top()); 31 q.pop(); 32 } 33 }else{ 34 // printf("%d %d\n",i,ans); 35 ans+=sum; 36 num=1; 37 sum=a[i]; 38 while(!q.empty())q.pop(); 39 q.push(a[i]); 40 } 41 } 42 43 ans+=sum; 44 printf("%I64d\n",ans); 45 return 0; 46 }
D. Compression
题意:
题目给出一个n*n的01矩阵,定义一个x-compression矩阵B,大小为n/x*n/x。使得A[i][j]=B[ceil(i/x)][ceil(j/x)]。显然当n能被x整除时才可能有B矩阵,但是这还不够,请你求出存在B时最大的x是多少。
留坑!
E. Vasya and Binary String
题意:
有一个长度为n的01序列,V要进行以下操作直到序列为空,选则一段连续的都是0或者都是1的子序列删除,然后合并两边剩余的序列。V每次删除一段长度为x的子序列就会得到a[x]分。V希望让得分最高,需要你来帮他!n<=100.
题解:我感觉是好题!
设f[i][j][k]为从i到j全部删除,i包括i前面有k个和i相同的。转移有两种:
1.把第i个和前面相同的一起删除。a[k]+f[i+1][j][1].
2.也可以枚举一个l,当第l个数字等于第i个数字的时候,先把i+1到l-1消掉,然后把第i个和第l个合并到一起。f[i+1][l-1][1]+f[l][j][k+1]。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 typedef long long LL; 7 const int maxn=100+10; 8 int n; 9 char s[maxn]; 10 int a[maxn]; 11 LL g[maxn]; 12 LL f[maxn][maxn][maxn]; 13 LL dp(int l,int r,int k){ 14 if(f[l][r][k])return f[l][r][k]; 15 if(l>r)return 0; 16 f[l][r][k]=dp(l+1,r,1)+g[k]; 17 for(int i=l+1;i<=r;i++){ 18 if(s[i]==s[l]){ 19 f[l][r][k]=max(f[l][r][k],dp(l+1,i-1,1)+dp(i,r,k+1)); 20 } 21 } 22 return f[l][r][k]; 23 } 24 25 int main(){ 26 scanf("%d",&n); 27 scanf("%s",s+1); 28 for(int i=1;i<=n;i++){ 29 scanf("%d",&a[i]); 30 g[i]=a[i]; 31 } 32 for(int i=2;i<=n;i++){ 33 for(int j=1;j<i;j++){ 34 g[i]=max(g[i],g[i-j]+g[j]); 35 } 36 } 37 LL res=dp(1,n,1); 38 printf("%I64d\n",res); 39 40 return 0; 41 }
F. Vasya and Endless Credits
题意:
V想要买一辆车,但是他自己一分钱也没有,于是他打算办一些信用卡。有n张信用卡可以选择,每张信用卡用ai,bi,ki来描述。银行会在开始的那个月初给V ai元钱,然后在之后的ki个月(包括开始的那个月)每个月的月末V要还bi元钱。每张信用卡只能用一次,V会在某个月的中间来买车,他能买车的价格为当前手里钱的总数,问V能买的车价格的最大值是多少?
题解:
二分图最大权匹配。假设我们已经知道在哪一天结束。那么左边的点为第i个贷款,右边的点为在倒数第i天贷款,那么左边每个点都要往右边连边,边权为a[i]-min(k,j)*b[i].然后这个题用费用流跑会T?
代码留坑。
G. Vasya and Maximum Profit
题意:
V决定办一场比赛来赚钱。有n个问题可以选择,第i个问题的难度为di,题目是按照难度递增的顺序给出的,且题目的难度各不相同。如果选择第i个问题,V需要付给作者ci元钱。对于比赛的每一道题,V可以获得a元钱。V需要从题目中选择连续的一段。如果V选择的一段是(l,r),那么还要支付gap(l,r)=max(di+1-di)^2.如果l=r,那么gap=0.请你帮忙计算V能获得的最大收益是多少。
题解:
待补···
(我这套刷了个P啊)