您的位置:首页 > 其它

The 2015 China Collegiate Programming Contest -ccpc-c题-The Battle of Chibi(hdu5542)(树状数组,离散化)

2015-11-06 22:09 393 查看
当时比赛时超时了,那时没学过树状数组,也不知道啥叫离散化(貌似好像现在也不懂)。百度百科——离散化,把无限空间中无限的个体映射到有限的空间中去,以此提高算法的时空效率。

这道题是dp题,离散化和树状数组用来优化,状态转移方程:dp[i][j]=sum(dp[i-1][k])----k需要满足a[j]>a[k]&&k<j;

i表示所要选的个数,j表示以第a[j]个数结尾所有的符合要求的递增串的个数,最后答案就是sum(dp
[j])--1<=j<=p;n 为要选的个数,p为所给数的总数,这个方程很容易想,这里不说了

(因为叫我说也说不清)。

数据肯定很大所以题目要求取模。

今天刚学树状数组还不太会用。

下面给出树状数组的模板

//[1,n]
int bit[MAX_N+1],n;
int sum(int i)
{
int s=0;
while(i>0)
{
s+=bit[i];
i-=i&-i;
}
return s;
}

void add(int i,int x)
{
while(i<=n)
{
bit[i]+=x;
i==i&-i;
}
}


View Code
为什么要离散化呢,因为N的范围为1000,而所给元素a[i]的范围为1e+9;

用树状数组时开不了那么大的数组,所以要离散化,将所给的数对应到1000以内连续的数,这样不会改变每个数之间的大小关系。

那么树状数组就可以开bit[1005];最后复杂度为n2log(n);

下面给出代码

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<map>
typedef long long ll;
ll sum(int n);
void add(int n,ll kk,int z);
ll dp[1005][1005];
int a[1005];
int b[1005];
int bit[1005];//树状数组
const ll pp=1e9+7;
using namespace std;
int main(void)
{
int n,i,j,k,p,q;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
map<int,int>my;//用来离散化的(将大的数转化1000以内的数)
memset(dp,0,sizeof(dp));
for(j=0; j<=1000; j++)
{
dp[1][j]=1;
}//当就选1个时全初始化1
scanf("%d %d",&p,&q);
for(j=1; j<=p; j++)
{
scanf("%d",&a[j]);
b[j]=a[j];
}
sort(b+1,b+p+1);//离散化前的排序比如200 300 100 排完为100 200 300 那么对应为1 2 3
int c[1005];
int cnt=1;
for(j=1; j<=p; j++)
{
if(j==1)
{
my[b[j]]=cnt;
}
else
{
if(b[j]!=b[j-1])
{
cnt++;
my[b[j]]=cnt;
}
else
{
my[b[j]]=cnt;
}
}
}
for(j=1; j<=p; j++)
{
a[j]=my[a[j]];
}//将原数组每个元素改为对应元素 200 100 300 -〉2 1 3
for(j=2; j<=q; j++)//要选的个数
{
memset(bit,0,sizeof(bit));
for(k=j-1; k<=p; k++)//可以改成从1循不过时间长
{
ll nn=sum(a[k]-1);
dp[j][k]=nn;
add(a[k],dp[j-1][k],cnt);
}
}
ll endd=0;
for(j=1; j<=p; j++)
{
endd=(endd+dp[q][j])%pp;
}
printf("Case #%d: ",i);
printf("%lld\n",endd);
}
return 0;
}
ll sum(int n)
{
ll s=0;
while(n>0)
{
s=(bit
+s)%pp;
n=n&(n-1);
}
return s;
}
void add(int n,ll kk,int z)
{
while(n<=z)
{
bit
=(kk+bit
)%pp;
n+=(n&(-n));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: