您的位置:首页 > 大数据 > 人工智能

2012 Multi-University Training Contest

2013-07-20 15:41 260 查看
HDU 4352

数位dp结合o(nlogn)的最长严格递增子序列

给定一个数的价值为 将该数字看成一个由单个数字排列成的序列,其最长严格递增子序列的长度就是该数的价值

给定一个区间 求该区间内价值为k的有多少个

nlogn的最长严格递增子序列的求法可以自行百度

#include <stdio.h>
#include <string.h>
#define LL __int64
int dit[50],K;
LL dp[19][2049][11];
void init()
{
for(int i=0;i<19;++i)
{
for(int j=0;j<(1<<10);++j)
{
for(int k=0;k<11;++k)
{
dp[i][j][k] = -1;
}
}
}
}
LL dfs(int limit,int sta,int pos,int k)
{
//printf("%d %d %d\n",sta,pos,k);
    if(pos<0)
return k==K;
if(!limit&&dp[pos][sta][K]!=-1)
return dp[pos][sta][K];
int end=limit?dit[pos]:9;
LL sum=0;
for(int i=0;i<=end;i++)
{
if(i==0&&sta==0)
{
sum+=dfs(limit&&(i==end),0,pos-1,k);
}
else
if((1<<i)&sta)
{
sum+=dfs(limit&&(i==end),sta,pos-1,k);
}
else if((1<<i)>sta)
{
sum+=dfs(limit&&(i==end),sta|(1<<i),pos-1,k+1);
}
else
{
int nst=0;
for(int j=i+1; j<=9; j++)
{
if((1<<j)&sta)
{
nst=(sta|(1<<i))^(1<<j);
break;
}
}
sum+=dfs(limit&&(i==end),nst,pos-1,k);
}
}
if(!limit)
dp[pos][sta][K]=sum;
return sum;
}
LL cal(LL n)
{
int cnt=0;
while(n>0)
{
dit[cnt++]=n%10;
n/=10;
}
return dfs(1,0,cnt-1,0);
}
int main()
{
int t,ca=0;
scanf ("%d",&t);
init();
while(t--)
{
LL l,r;
ca++;
scanf ("%I64d%I64d%d",&l,&r,&K);
printf("Case #%d: %I64d\n",ca,cal(r)-cal(l-1));
}
}

HDU 4357

该题可以推出结论 当字母多于3个时,其中任意两个可以互换

这样只需要特殊处理只有两个字母的情况就可以了

#include<stdio.h>
#include <string.h>
int main ()
{
char s1[100],s2[100];
int t;
scanf ("%d",&t);
for(int ca=1;ca<=t;ca++)
{
scanf ("%s%s",s1,s2);
int len=strlen(s1);
if(len>2)
{
int sum=0;
for(int i=0;i<len;i++)
sum+=(s1[i]-'a'+s2[i]-'a');
if(sum&1)
printf("Case #%d: NO\n",ca);
else
printf("Case #%d: YES\n",ca);
}
else
{
int ans1=s2[0]-s1[1]+52;
int ans2=s2[1]-s1[0]+52;
int ans3=s2[0]-s1[0]+52;
int ans4=s2[1]-s1[1]+52;
if((ans1==ans2&&(ans1&1))||(ans3==ans4&&(ans3%2==0)))
printf("Case #%d: YES\n",ca);
else
printf("Case #%d: NO\n",ca);
}
}
}

HDU4359

这道是组合数学以及动态规划

由于2的n次方大于1到n-1次方的和

所以只需要将2的n次方放在右子树即可满足题目要求

剩下的就是分配子树节点个数

没了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: