cjx晚自习听听力被其他学校的教练发现了
上午
数位DP-原题传送门
T1 赛时不知道为什么爆了,又喜提一次爆蛋。当然比赛标题都跟我们说了是数位DP了,就直接往数位DP上考虑。这题算是数位DP的类板子题,判断条件涉及三个数位,又要标记两个数字是否出现,所以在开数组时会喜提一个5–7维的数组,不过由于每一维都很 小 ,所以问题不大。理论上数位DP有两种做法,一种是dfs,另一种是递推比较像DP,但由于dfs比较好理解我选择dfs。我开的DP数组达到了六维,分别对应当前位置、前一个、前两个位置、4是否出现、8是否出现、当前位数是否合法,然后将每一位数处理出来后就开始快乐地dfs了。然而一交上去直接
WA |
了,然后慢慢调(后来我把标程往我的代码的方向改,标程和我的代码都要一样了还是对的),最后终于把标程改错了,然后我的程序的问题就解决了,交上去直接AC了。问题出在把一个每一层dfs都会用到并更新的变量定义成了全局变量,导致每一次dfs那个值都在不断累加最后使答案偏离。
贴个代码
#include
using namespace std;
long long int L,R,dp[15][15][15][3][3][3],l,st[13],ans,pas,pbs,pds,dpt;
bool v[15][15][15][3][3][3];
long long int dfs(int p,int x,int y,int sta,int pa,int pb,int pd)
{
long long int res=0;
if(pa==1&&pb==1)
{
return 0;
}
if(p==0)
{
return sta;
}
if(!pd&&v[p][x][y][sta][pa][pb]==1)
{
return dp[p][x][y][sta][pa][pb];
}
int mx=9;
if(pd)
{
mx=st[p];
}
for(int i=0;i<=mx;i++)
{
int stap=sta,pap=pa,pbp=pb,pdp=0;
// if(dpt==14)
// {
// cout<<pap<<" -- "<<pa<<endl;
// }
// if(dpt==14)
// {
// cout<<" ----- "<<pap<<endl;
// }
if((x==i&&y==i))
{
stap=1;
}
if(i==4)
{
pap=1;
}
if(i==8)
{
pbp=1;
}
if(i==mx&&pd==1)
{
pdp=1;
}
dpt++;
res+=dfs(p-1,i,x,stap,pap,pbp,pdp);
}
if(pd==0)
{
dp[p][x][y][sta][pa][pb]=res;
v[p][x][y][sta][pa][pb]=1;
}
return res;
}
long long int sl(long long int a)
{
l=0;
long long int xx=a;
for(int i=1;i<=11;i++)
{
st[i]=xx%10;
// cout<<"st== "<<st[i]<<endl;
xx/=10;
}
for(int i=0;i<=12;i++)
{
for(int ii=0;ii<=12;ii++)
{
for(int iii=0;iii<=12;iii++)
{
for(int j=0;j<=1;j++)
{
for(int jj=0;jj<=1;jj++)
{
for(int jjj=0;jjj<=1;jjj++)
{
dp[i][ii][iii][j][jj][jjj]=0;
v[i][ii][iii][j][jj][jjj]=0;
}
}
}
}
}
}
ans=0;
for(int i=1;i<=st[11];i++)
{
pas=0;
pbs=0;
pds=0;
if(i==8)
{
pbs=1;
}
if(i==4)
{
pas=1;
}
if(i==st[11])
{
pds=1;
}
// cout<<"10 "<<i<<" "<<pas<<" "<<pbs<<" "<<pds<<endl;
// cout<<dfs(10,i,0,0,pas,pbs,pds)<<endl;
// coutR;
// if(r-l<=1000000)
// {
//
// }
// else
{
cout<<sl(R)-sl(L-1)<<endl;
}
}
T3 还在改
下午
T2 诈骗题,考试时一分没骗到,链的情况根节点不一定(一定不)在链的末端,所以输出
,然后40分到手。过于简单代码不贴。2 2
`。所有点都跟根节点连边的情况下,先手必胜,所以输出
`n-1 n-1
代码如下
//40pts
#include
using namespace std;
int n,s,t,p;
int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
cin>>n;
p=1;
for(int i=1;i>s>>t;
if(s!=1&&t!=1)
{
p=0;
}
}
if(p==1)
{
cout<<n-1<<" "<<n-1<<endl;
}
else
{
cout<<"2 2"<<endl;
}
}