2021年1月23日预备役第一周总结
简单了解了动态规划
其中01背包问题将二维dp压缩成了一维来节约空间
二维
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(j-w[i-1]>=0)
{
dp[i][j]=max(dp[i-1][j],dp[i][j-w[i-1]]+v[i-1]);
}
else dp[i][j]=dp[i-1][j];
}
}
一维度
for(int i=1;i<=k;i++)
{
for(int j=v;j>=a[i];j--)
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
}
问题 C: 签到送气球
描述
ACM-ICPC程序设计大赛是大学级别最高的脑力竞赛,素来被冠以"程序设计的奥林匹克"的尊称。大赛至今已有近40年的历史,是世界范围内历史最悠久、规模最大的程序设计竞赛。比赛形式是:从各大洲区域预赛出线的参赛队伍,于指定的时间、地点参加世界级的决赛,由1个教练、3个成员组成的小组应用一台计算机解决7到13个生活中的实际问题。在正式赛场中,一个队伍每解决一个新的问题就会有一个相应的气球作为奖励送到这个队伍所在的位置。
LBG作为这次ACM-ICPC的志愿者,当然是时刻关注着场上的过题情况的,每当有一个队伍通过新的问题的时候,他就会马上送上气球。但由于参赛队伍实在是太多了,他也不清楚每个队伍得到了多少个气球。在比赛结束之后,他拿到了一份这场比赛的题目提交情况,他想知道现场参加比赛的队伍每个队伍能获得多少个气球,聪明的你能帮帮他吗?
格式
输入格式
第一行包含一个整数T(T<=10),表示总共有T组测试样例;
第二行输入一个整数n,m;
n表示有多少个队伍参加这次的比赛(1<=n <= 50);
m表示有多少条提交记录(1<=m<=1000);
接下来输入m行,每行输入格式如下:
team_id problem_id submit_status
team_id 代表着队伍的编号(1 <= team_id <= n);problem_id代表着题目编号(为A~M的大写字母);submit_status代表着这个题目提交的结果(可能是"AC",“PE”,“TLE”,“MLE”,“WA”,“RE”,"CE"其中的一种)。
输出格式
对于每组样例
第一行输出一行“Case #x:”,x表示当前为第几组样例(详细见样例);
第二行输出n个数(每两个数之间用空格隔开)代表着第 i 个队可以获得的气球数量。(注意不要在每一行的末尾输出多余的空格)。
样例
样例输入 Copy
1
5 10
1 A WA
1 A AC
2 A AC
3 C TLE
2 C TLE
1 C AC
3 A AC
4 A AC
1 A AC
5 A WA
样例输出 Copy
Case #1:
2 1 1 1 0
上题目 用二维数据来记录是不是刷过题 就不用循环判断来去掉重复
简单博弈之巴什博弈
二分答案
因为最近用二分太多了
然后今天出了个问题
这个题目使用了二分
贴一下二分代码
月色真美 12:41:55
#include<stdio.h>
#define ll long long
ll a[10000005];
int check(int ans,ll a[],int n,int k)//判断ans个长度 是不是存在有和为k的数据块
{
ll sum=0;
for(int i=0;i<=n-ans;i++)
{
sum=a[ans+i]-a[i];
if(sum==k)return 1;
}
return 0;
}
int main()
{
int n;
scanf("%d",&n);
int k;
scanf("%d",&k);
a[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",a+i);
a[i]+=a[i-1];
}
int l=-1;
int r=n+1;
while(l<=r)
{
int mid=(r+l)/2;
if(check(mid,a,n,k))
{
l=mid+1;
}
else r=mid-1;
}
if(r<0)printf("-1\n");
else printf("%d\n",r);
}
利用二分和前缀和
二分这里出来问题
不能由check函数值来确定答案区间
然后尺取出来了
因为卡时间 所有就用了快读(虽然不是很理解这个快读)
#include<stdio.h>
#include<ctype.h>
typedef long long ll;
ll a[20000007];
int max(int a,int b)
{
if(a>b)return a;
else return b;
}
inline ll read()
{
char c=getchar();
ll x=0;
while(!isdigit(c))c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x;
}
int main()
{
int n;
ll k;
scanf("%d",&n);
k=read();
for(int i=1;i<=n;i++)
a[i]=read();
//for(int i=1;i<=n;i++)
//printf("%lld ",a[i]);
int l=1;
int r=1;
ll sum=a[1];
int x=-1;
if(sum==k)x=1;
while(r<=n)
{
if(sum==k)x=max(r-l+1,x);
if(sum<=k&&r<=n)sum+=a[++r];//如果比k小酒延时右边区间
while(sum>k&&l<=r)
{
sum-=a[l++];
}
}
printf("%d\n",x);
}