奋斗群群赛16总结与心得

来源:互联网 发布:交换机端口号怎么看 编辑:程序博客网 时间:2024/05/18 16:13

  • 总体情况
  • T1
    • 题目
    • 思路
  • T2
    • 题目
    • 思路
  • T3
    • 题目
    • 思路
  • T4
    • 题目
    • 思路
  • T5
    • 题目
    • 思路
  • T6
    • 题目
    • 思路

总体情况

https://vjudge.net/contest/187296
昨天在CF上打过的题目又在这里出现了,而且前两题被删掉了,后面的题我不会做差一点点就爆零了,还好我能A第4题.我去CF上瞄了一眼,掉了78分.

T1

题目

http://codeforces.com/problemset/problem/864/C

思路

我都懒得说思路了.看代码吧.我非常渣的英语说明,勿喷.中文会被坑成乱码.

#include<bits/stdc++.h>using namespace std;//Excuse me,my English is poor.int a,b,f,k;int main(){int i,j,result=0,stop;//When the bus goes to the a point or the zero point, it can contain stop liters of gascin>>a>>b>>f>>k;if (k>2&&b<2*f||k>1&&b<2*(a-f)||b<f||b<a-f) return printf("-1"),0;//The tank is so smallstop=b;for (i=1;i<=k;i++)  {  if (i==k&&stop>=a) break;//If the bus goes to the final journey and has more than b liters of gas,it can go through the road  if (i&1)//to a point    {    if (stop<2*a-f) result++,stop=b-a+f;//The bus can't go past the gas station twice,so it will refuel its tank     else stop-=a;//finish a journey    }  else //to zero point    {    if (stop<a+f) result++,stop=b-f;//The zero point is same     else stop-=a;    }  }cout<<result;}

T2

题目

http://codeforces.com/problemset/problem/864/D

思路

从头开始扫,出现重复的话用目前最小的没用过的数字去替换.

#include<bits/stdc++.h>using namespace std;const int boss=2e5;int a[boss+10],b[boss+10],c[boss+10],d[boss+10],sum;int main(){int n,i,j;cin>>n;for (i=1;i<=n;i++)   {  scanf("%d",&a[i]);  b[a[i]]++;  }for (i=1;i<=boss;i++) if (b[i]) sum++;cout<<n-sum<<endl;for (i=1,j=1;i<=n;i++) if (b[a[i]]>1)   {  while (b[j]>0) j++;  if (j<a[i]||c[a[i]]==1)    {    d[i]=j;b[j]=1;b[a[i]]--;    }  else d[i]=a[i],c[a[i]]=1;  }else d[i]=a[i];for (i=1;i<=n;i++) printf("%d ",d[i]);}

T3

题目

http://codeforces.com/problemset/problem/864/E

思路

这题是个简单01背包,只是要输出选择物品的编号。结构体存储4个数据,在开始背包之前一定要以物品被毁的时间从小到大排序,否则会影响最后的答案。用一个二维数组vector存储物品编号,扫dp数组的时候每当扫到最大值就更新一次选择物品的位置。

#include<bits/stdc++.h>using namespace std;struct loop{int st,bt,v,num;}object[2010];//savetime,broketime,value,numbervector<int> v[2010];int dp[2010],position,i,j,n,answer;bool cmp(loop a,loop b){return a.bt<b.bt;}int main(){cin>>n;for (i=1;i<=n;i++) scanf("%d%d%d",&object[i].st,&object[i].bt,&object[i].v),object[i].num=i;sort(object+1,object+n+1,cmp);for (i=1;i<=n;i++) for (j=object[i].bt-1;j>=object[i].st;j--) if (dp[j-object[i].st]+object[i].v>dp[j])//背包  {  dp[j]=dp[j-object[i].st]+object[i].v;  v[j]=v[j-object[i].st];//把背包中的物品进行下一步的转移  v[j].push_back(object[i].num);//把该物品的编号推入背包  }for (i=0;i<=2000;i++) if (dp[i]>answer) answer=dp[i],position=i;//求最大值,找出该最大值所在位置的所有物品编号printf("%d\n%d\n",answer,v[position].size());for (i=0;i<v[position].size();i++) printf("%d ",v[position][i]);} 

T4

题目

http://codeforces.com/problemset/problem/855/B

思路

i<=j<=k,可利用数组储存m位置之前和之后最大最小的数,从头到尾一顿暴枚就可以了.一开始我看错了题目,把i<=j<=k这个条件忘了,然后直接贪心就WA了.

#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll boss=2e5,index=1e18;ll a[boss+10],qianmax[boss+10],qianmin[boss+10],houmax[boss+10],houmin[boss+10];int main(){int i;ll n,p,q,r,result,answer=-3*index;cin>>n>>p>>q>>r;for (i=1;i<=n;i++) scanf("%I64d",&a[i]);qianmax[0]=-index;qianmin[0]=index;for (i=1;i<=n;i++) qianmax[i]=max(qianmax[i-1],a[i]),qianmin[i]=min(qianmin[i-1],a[i]);//前缀最大最小houmax[n+1]=-index;houmin[n+1]=index;for (i=n;i>=1;i--) houmax[i]=max(houmax[i+1],a[i]),houmin[i]=min(houmin[i+1],a[i]);//后缀最大最小for (i=1;i<=n;i++)  {  result=0;  if (p>=0) result+=p*qianmax[i];  else result+=p*qianmin[i];  result+=q*a[i];  if (r>=0) result+=r*houmax[i];  else result+=r*houmin[i];  answer=max(answer,result);  }cout<<answer;}

T5

题目

http://codeforces.com/problemset/problem/855/C

思路

树形dp,代码还是很好理解的.利用0,1,2三个状态,0即小于k,此时0,1,2三个状态均可;1即=k,此时dp只能递推小于k的情况;同理大于k的时候能递推0,2两个状态.

#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll boss=1e5,mod=1e9+7;ll n,m,k,x,a,b,answer,dp[boss+10][18][3],temp[18][3];vector<ll> v[boss+10];void dfs(ll father,ll xianzai){int r,i,j;dp[xianzai][0][0]=k-1,dp[xianzai][1][1]=1,dp[xianzai][0][2]=m-k;for (r=0;r<v[xianzai].size();r++) if (v[xianzai][r]!=father)  {  dfs(xianzai,v[xianzai][r]);  memset(temp,0,sizeof(temp));  for (i=0;i<=x;i++) for (j=0;j<=i;j++)    {    temp[i][0]=(temp[i][0]+(dp[xianzai][i-j][0]*dp[v[xianzai][r]][j][0])%mod)%mod;    temp[i][0]=(temp[i][0]+(dp[xianzai][i-j][0]*dp[v[xianzai][r]][j][1])%mod)%mod;    temp[i][0]=(temp[i][0]+(dp[xianzai][i-j][0]*dp[v[xianzai][r]][j][2])%mod)%mod;    temp[i][1]=(temp[i][1]+(dp[xianzai][i-j][1]*dp[v[xianzai][r]][j][0])%mod)%mod;    temp[i][2]=(temp[i][2]+(dp[xianzai][i-j][2]*dp[v[xianzai][r]][j][0])%mod)%mod;    temp[i][2]=(temp[i][2]+(dp[xianzai][i-j][2]*dp[v[xianzai][r]][j][2])%mod)%mod;    }  for (i=0;i<=x;i++)     {    dp[xianzai][i][0]=temp[i][0];    dp[xianzai][i][1]=temp[i][1];    dp[xianzai][i][2]=temp[i][2];    }     }}int main(){int i;scanf("%I64d%I64d",&n,&m);for (i=1;i<n;i++)   {  scanf("%I64d%I64d",&a,&b);  v[a].push_back(b);  v[b].push_back(a);  }scanf("%I64d%I64d",&k,&x);dfs(-1,1);for (i=0;i<=x;i++) answer=(answer+dp[1][i][0]+dp[1][i][1]+dp[1][i][2])%mod;printf("%I64d",answer);}

T6

题目

http://codeforces.com/problemset/problem/855/E

思路

本题为数位DP,利用数组中数位作为状态转移之.

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int boss=1e5;ll dp[11][66][2233][2];int bit[66]; //dp数组第1位记录进制,第二位数字长度,第三位各位状态,第4位是否有前导0ll dfs(int jinzhi,int len,int zhuangtai,int qiandao0,int xianzhi){int i;if (len==0) return !zhuangtai;if (!xianzhi&&dp[jinzhi][len][zhuangtai][qiandao0]!=-1) return dp[jinzhi][len][zhuangtai][qiandao0];ll result=0;int da=xianzhi!=0?bit[len]:jinzhi-1;for (i=0;i<=da;i++)    {  if (!i&&qiandao0) result+=dfs(jinzhi,len-1,zhuangtai,1,xianzhi&(i==da));  else result+=dfs(jinzhi,len-1,zhuangtai^(1<<i),0,xianzhi&(i==da));  }  return !xianzhi&&!qiandao0?dp[jinzhi][len][zhuangtai][qiandao0]=result:result;}ll jisuan(ll n,int jinzhi){int l=0;while (n)  {  bit[++l]=n%jinzhi;  n/=jinzhi;  }return dfs(jinzhi,l,0,1,1);}int main(){ios::sync_with_stdio(0);cin.tie(0); //加速cin和coutmemset(dp,-1,sizeof(dp));int t;cin>>t;while (t--)  {  int b;ll l,r;  cin>>b>>l>>r;  cout<<jisuan(r,b)-jisuan(l-1,b)<<endl;  }}
原创粉丝点击