A - Add Candies
题面:题面有点绕,总结一下就是有n个长度的数组,数组值跟下标值一样,a[i]=i;然后问你第i次操作,选一个数组中的值,除了它其他都加i,使得数组值相同,问随机一种情况
思路:操作n次,输出1,2,3,4,5 … n即可
B - Numbers Box
题面:给一个n,m的矩阵,有正负,有操作选两个相邻的值,同乘-1,求这个矩阵最大的之和
思路:比赛的时候卡了,因为没想清楚,选了个最小的负数,其实,正解是如果出现奇数个负数,选择最小的abs值,偶数个负数就肯定能全部变正
比赛的时候队友飞快过三题,然后我还在卡B,如果不是队友提醒,可能卡死了
C - Knapsack
题面:给两个数n,w,给n长度数组,求数组里选几个有没有w/2~w范围的值
思路:第一想法背包,但数据n 2e5,w 1e18,好,肯定不行,换一个,排序然后尺取?,于是写了一下,就过了
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define lson(x) x<<1
#define rson(x) x<<1|1
#define mod 998244353
using namespace std;
ll ksm(ll a,ll b){
ll ans=1;
while(b){
if(b&1){
ans*=a;ans%=mod;
}
a*=a;a%mod;
b>>=1;
}
}
const int N=2e5+10;
int n,m,t;
ll w;
ll dp[N];
struct node{
int w,num;
friend bool operator<(const node a,const node b){
return a.w<b.w;
}
}we[N];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%lld",&n,&w);
int f=1,pos;
for(int i=0;i<n;i++){
scanf("%lld",&we[i].w);we[i].num=i+1;
if(we[i].w*2>=w && we[i].w<=w){
f=0;pos=i;
}
}
if(!f){
printf("1
");
printf("%d
",we[pos].num);
continue;
}
sort(we,we+n);
dp[0]=we[0].w;
for(int i=1;i<n;i++){
dp[i]=dp[i-1]+we[i].w;
}
for(int i=0;i<n;i++){
if(dp[i]*2>=w && dp[i]<=w){
f=0;pos=i;break;
}
if(dp[i]*2>=w && dp[i]>w){
f=2;pos=i;break;
}
}
int pos2=0;
if(f==2){
for(int i=0;i<pos;i++){
while((dp[pos]-dp[i])*2<w){pos++;if(pos>n){break;}}
if((dp[pos]-dp[i])*2>=w &&(dp[pos]-dp[i])<=w){f=0,pos2=i;break;}
}
}
if(!f){
printf("%d
",pos-pos2+1);
for(int i=pos2;i<=pos;i++){
printf(i==pos?"%d
":"%d ",we[i].num);
}
}
else{
printf("-1
");
}
}
return 0;
}
D - Catching Cheaters
题面:给n,m两个小于5000的数字,然后输入两个长度为n,m 的字符串s1,s2,取两个子串s1’,s2’长度分别是x,y,求4 * lcs(s1’,s2’)-x-y的最大值
思路:枚举二分贪心wa,因为没考虑n长度字符串的选子串的字母,是个假算法。所以这道题正解就是dp,每次dp题,贪心贪出事。
那么方法就是,每次找到相同的字符,就会对前一个状态+2,如果没有相同,就会有两种选择,移动s1一位,or移动s2一位,每移动一位值就会-1
这样我们就可以列出状态转移方程
s1[i]==s2[j] 的情况比较 dp[i-1][j-1]+2 dp[i-1][j]-1(大于等于0) dp[i][j-1]-1(大于等于0) 哪个大
s1[i]!=s2[j] 的情况比较 dp[i-1][j]-1(大于等于0) dp[i][j-1]-1(大于等于0) 哪个大
然后找dp[i][j]的最大值即可
代码:
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define lson(x) x<<1
#define rson(x) x<<1|1
#define mod 998244353
using namespace std;
ll ksm(ll a,ll b){
ll ans=1;
while(b){
if(b&1){
ans*=a;ans%=mod;
}
a*=a;a%mod;
b>>=1;
}
}
const int N=5e3+10;
int n,m,t;
char s[N],ss[N];
int dp[N][N];
int main(){
scanf("%d%d",&n,&m);
scanf("%s",s);
scanf("%s",ss);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(s[i]==ss[j]){
dp[i+1][j+1]=max(dp[i][j]+2,max(max(dp[i+1][j]-1,0),max(dp[i][j+1]-1,0)));
}
else{
dp[i+1][j+1]=max(max(dp[i+1][j]-1,0),max(dp[i][j+1]-1,0));
}
}
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
ans=max(dp[i][j],ans);//cout<<dp[i][j]<<" ";
}
//cout<<endl;
}
printf("%d
",ans);
return 0;
}