HDU4055
给一个I、D、?组成的字符串长度为n,那么有n+1个数字,数字要求满足对有I,数字递增。有D,数字递减,有?,数字随意
比如131就满足ID,ID的所有数字有132,231.给一个字符串问有多少种方案。
这里假设一个dp[i][j]表示长度为i的字符串,结尾数字是j有dp[i][j]种方法。
这里有个大前提,就是结尾为j的时候,把所有大于j的数字+1,就可以得到之前无j的所有排列,且满足题意
那么转移可以这样想,对于‘I’,dp[i][j]=dp[i-1][1~j-1]进行累加,表示由之前的低位转移过来,表示之前没有j这个数字,把所有数字+1,就仍然可以满足题目所给条件。
对于'D',dp[i][j]=dp[i-1][j~i]就仍然相当把所有大于j的数字+1,j还要就是因为其在新的转移中变成了j+1
对于?,就是D+I的结果。
wa:有'取模'与‘-’的运算,必须+mod,因为有可能大的数字mod后变小了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1007;
const ll mod=1e9+7;
ll dp[maxn][maxn];
ll dp2[maxn][maxn];
char s1[maxn];
int main(){
ll i,j,k,f1,f2,f3,f4,t1,t2,t3,t4,n,m;
ll Max;
ll T;
freopen("in.txt","r",stdin);
while(scanf("%s",s1+1)==1){
ll len1=strlen(s1+1); //注意这里为 是s1+1
memset(dp,0,sizeof(dp));
memset(dp2,0,sizeof(dp2));
dp[1][1]=1;
dp2[1][1]=1;
for(i=2;i<=len1+1;i++){
for(j=1;j<=i;j++){
if(s1[i-1]=='I'){ //增加,j,(1-j)
dp[i][j]=dp2[i-1][j-1];
}else if(s1[i-1]=='D'){
dp[i][j]=(mod+dp2[i-1][i-1]-dp2[i-1][j-1])%mod;
}else{
dp[i][j]=dp2[i-1][i-1];
}
}
for(j=1;j<=i;j++)
dp2[i][j]=(dp2[i][j-1]+dp[i][j])%mod;
}
ll res=0;
for(i=1;i<=len1+1;i++)
res=(res+dp[len1+1][i])%mod;
printf("%lld\n",res);
}
return 0;
}
hdu2196:
题意:范围1e4, 给一棵树,求出每个结点能到的最远距离。
考虑每个结点的最远点距离多少,一个结点的最远距离要么是其子节点/要么是其父亲结点连接的最远结点(第二远结点,因为最远可能是连接的这个结点,然后每个点判断其最远和次远(第一个如果是父节点,那么最远的2个就按排序后的第二与第三。
重点在于到子结点以后,父节点与其的距离不知道,此时dfs传下来,需要每次都传父节点到子节点的距离.如果选择是父节点的点且不是自己,那么需要加上自己到父节点的距离。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e5+8;
const ll mod=1e9+7;
ll q1[maxn];
struct ttt{
ll num,key;
};
ttt dp[10005][2];//0表示最小,1表示c次小
ttt res[10005][2];
vector<ttt>qq[10050];
ll dfs(ll x,ll fa){
if(qq[x].size()==1&&fa!=-1){
;
}else{
ll i,u,len;
ll t1,t2,num1,num2;
t1=t2=0;
num1=num2=-1;
for(i=0;i<qq[x].size();i++){
u=qq[x][i].num;
len=qq[x][i].key;
if(u==fa)continue;
dfs(u,x);
if(t1==0){
t1=dp[u][0].key+len;
num1=u;
continue;
}
if(dp[u][0].key+len>=t2){
t2=dp[u][0].key+len;
num2=u;
}
if(t2>t1){
swap(t2,t1);
swap(num2,num1);
}
}
dp[x][0].num=num1;dp[x][0].key=t1;
dp[x][1].num=num2;dp[x][1].key=t2;
}
}
ll cmp(ttt x,ttt y){
return x.key>y.key;
}
ttt max1[4];
ll dfs2(ll x,ll fa,ll len){
ll i,u;
max1[2]=res[fa][0];max1[3]=res[fa][1];
if(fa==-1){
res[x][0]=dp[x][0];
res[x][1]=dp[x][1];
}else{
max1[0]=dp[x][0];
max1[1]=dp[x][1];
if(max1[2].num!=x){
max1[2].key+=len;
}
if(max1[3].num!=x){
max1[3].key+=len;
}
sort(max1,max1+4,cmp);
if(max1[0].num==x){ //最小与次小均是
res[x][0]=max1[1];
res[x][1]=max1[2];
}else{
res[x][0]=max1[0];
if(max1[1].num==x){
res[x][1]=max1[2];
}else{
res[x][1]=max1[1];
}
}
}
for(i=0;i<qq[x].size();i++){
u=qq[x][i].num;
if(u==fa)continue;
dfs2(u,x,qq[x][i].key);
}
}
int main(){
ll i,j,k,f1,f2,f3,f4,t1,t2,t3,t4,n,m;
//freopen("in.txt","r",stdin);
while(scanf("%lld",&n)==1){
memset(res,0,sizeof(res));
memset(dp,0,sizeof(dp));
ttt u,v;
for(i=1;i<=n;i++)
qq[i].clear();
for(i=2;i<=n;i++){
scanf("%lld %lld",&t1,&t2);
u.num=t1;u.key=t2;
qq[i].push_back(u);
u.num=i;
qq[t1].push_back(u);
}
dfs(1,-1);
dfs2(1,-1,0);
for(i=1;i<=n;i++)
printf("%lld\n",res[i][0].key);
}
return 0;
}