T1:首先你要发现,对于任意一个奇数i,i xor (i-1)=1;
那么我们可以将答案转化为统计有多少个1相互异或起来;
所以答案就那么几种;
如果你用的数位DP,只能说明你太高估day1T1了;
#include <bits/stdc++.h> using namespace std; long long l,r,ans1,ans2; int main () { int t; cin>>t; while(t--){ cin>>l>>r; if(l>r) swap(l,r); --l; ans1=0; ans2=0; if(l&1) { long long tmp=l/2; if(tmp&1){ ans1^=0; } else{ ans1^=1; } } else{ ans1^=l; --l; long long tmp=l/2; if(tmp&1){ ans1^=0; } else{ ans1^=1; } } if(r&1) { long long tmp=r/2; if(tmp&1){ ans2^=0; } else{ ans2^=1; } } else{ ans2^=r; --r; long long tmp=r/2; if(tmp&1){ ans2^=0; } else{ ans2^=1; } } cout<<(ans1^ans2)<<endl; } }
T2:
#include <iostream> #include <cstdio> #pragma GCC optimize(2) using namespace std; int n,m,p; struct littlestar{ int to; int nxt; int w; }star[10300000]; int head[10300000],cnt; void add(int u,int v,int w) { star[++cnt].to=v; star[cnt].w=w; star[cnt].nxt=head[u]; head[u]=cnt; } int floor,tot; int have[20]; int ans=999999999; int dis[10300000],vis[10300000],q[10300000]; void spfa() { for(register int i=1;i<=tot;i++) { dis[i]=999999999; } dis[1]=0; vis[1]=1; int h=1,t=1; q[1]=1; while(h<=t){ int u=q[h]; for(register int j=head[u];j;j=star[j].nxt){ int v=star[j].to; if(dis[v]>dis[u]+star[j].w){ dis[v]=dis[u]+star[j].w; if(!vis[v]){ q[++t]=v; vis[v]=1; } } } vis[u]=0; ++h; } } int main () { //freopen("library.in","r",stdin); cin>>n>>m>>p; floor=1<<p; tot=n*floor; for(register int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); for(register int j=0;j<floor;j++){ add(n*j+x,n*j+y,z); add(n*j+y,n*j+x,z); } } for(register int k=1;k<=p;k++){ int x,u,v,w; scanf("%d%d%d%d",&x,&u,&v,&w); for(register int i=0;i<floor;i++){ for(register int j=1;j<=p;j++){ if(i&(1<<(j-1))){ have[j]=1; } else have[j]=0; } if(have[k]==1){ add(n*i+u,n*i+v,w); add(n*i+v,n*i+u,w); } int tmp=i^(1<<(k-1)); add(n*tmp+x,n*i+x,0); } } spfa(); for(register int i=0;i<floor;i++){ ans=min(ans,dis[i*n+n]); } cout<<ans<<endl; }
T3:
我们首先看到这个题目后,我们可能会想到贪心合并,每次发现不能构成单调不减序列后,我们就一直合并到能构成单调不减序列.这是错误的!因为我们没有保证在相同合并次数下,要尽量使得最后一个数尽量小。所以会想到DP开始思考DP思路设:f[i]表示前i个数合并最小次数g[i]表示前i个数保证在合并f[i]次的情况下,最后一个数的最小值。转移的话,假如我们在处理f[i]那么我们在[1,i]枚举j,假如从j到i这个区间的值的和大于等于g[j](代表一定要合并),那么就可以转移了(合并)那么f[i]=