The journey of Ural dynamic programming

The journey of Ural dynamic programming

 

一句话概括Ural的dp,输出路径+滚动数组。下文中,#是注意点,$是小优化。3Q for

YY’s Code.

 

 

一、经典题

l  1146联系大白书P55

l  1017 Sol1:dp[i][j]=sum{dp[i-j][k]} ;(0<=k<j)   

            Sol2:dp[i+j]+=dp[j]; (0<=j<n) 视为背包问题来理解

l  1303 代码贪心,甚至不需排序。

l  1223朱晨光:《优化,再优化!——从《鹰蛋》一题浅析对动态规划算法的优化》

l  1513 f[i]=sum{f[i-1-j]}(+B+jL)(0<=j<=m)

l  1238 区间dp

l  1276 类似noip2009乌龟棋。#1:火车第一节车厢的头也要和最后一节车厢的尾相匹配。

二、难题:

l  1260 dp[n]=dp[n-1](12……)+ dp[n-3](132……)+1(1357……,根据n奇偶性略有不同)

l  1627 周冬:《生成树的计数及其应用》

l  1171 http://blog.csdn.net/chm517/article/details/18889199

l  1459 代码插头DP+矩阵快速幂

三、好题:

l  1117 代码一般读入[a,b]就可以考虑[1,b]-[1,a-1]

l  1310 代码(类似的题有Spoj 2319)

l  1427 贪心略有坑,写着渣的代码会在n=1时跪了。

l  1900 dp[i][j] = max(dp[i][j],dp[g][j-1]+o[i][i+1]-o[g][i+1])

l  1577 代码If in your current state s1[i]==s2[j], you should not assume states i+1,j and i,j+1. Only i+1,j+1.test:aa/ac

l  1696 代码dp[N][最大值][出现在最大值后的严格小于最大值的尽可能大的值]

l  1552 代码通过27-10进制转化成功优化了一维,代码还很优雅

l  1745 http://blog.csdn.net/chm517/article/details/21652557

l  1526 代码关键在于状态的设计,有点区间的味道,但只需考虑区间长度,还有一维是状压

l  1476预处理的优化http://blog.csdn.net/chm517/article/details/21751089

l  1655代码#1:初始位置那个点的限制时间为inf

l  1739代码

l  1895代码$1:第一维的1000可以降为50*2;  $2:代码中两个break。

四、概率题

l  1776代码

l  1716 http://blog.csdn.net/chm517/article/details/21655187 (类似的有Codeforces  148D Bag of mice)

l  1887 基本同hdu 4336


//ural 1303
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
const int inf=0x3f3f3f3f;
using namespace std;
#define N 100005
int n,m,o;
int ans[N],r[N];
void doit()
{   memset(r,0,sizeof(r));
    int x,y,ori,t;
    for (int i=1;;i++)
         {scanf("%d%d",&x,&y);
          if (x<0) t=0;else t=x;
          if (y>r[t]) {r[t]=y; if (t==0) ori=x;}
          if (x==0&&y==0) {n=i-1; break;}
         }
    o=0;
    int L=0,R=0,i=0,id;
    while (L<m)
        {   while (i<=L)
                 {   if (R<r[i]){R=r[i];id=i;}
                     i++;
                 }
            if (L==R) {printf("No solution\n"); return;}
            ans[++o]=id;
            L=R;
        }



    printf("%d\n",o);
    for (int i=1;i<=o;i++)
        if (ans[i]==0)printf("%d %d\n",ori,r[0]);
                else printf("%d %d\n",ans[i],r[ans[i]]);
}
int main()
{   while (scanf("%d",&m)!=EOF) doit();
}

//ural 1459
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define MAX 22
typedef long long LL;
using namespace std;
const int HASH=4096;
const int INF=0x3f3f3f3f;
const LL mod=1000000000;
int n,m;
int id[HASH];
int jz[6];
int ex,ey,o;
int HA;
class Mat{
public:
    LL s[MAX][MAX];
    int sizei,sizej;
public:
    Mat(int a=MAX,int b=MAX,int type=0);
    void clear(int type = 0);
    void ReSize(int a = MAX,int b=MAX,int type=0);
    void Add(const Mat& B);
    void Sub(const Mat& B);
    void CopyMat(const Mat& B);
    void Multiply(const Mat &B);
    void Er_work(int n);
    void solve(int p) ;

};

Mat::Mat(int a,int b,int type):sizei(a),sizej(b)
{   memset(s,0,sizeof(s));
         if(type==1)
            for(int i=0;i<min(a,b);i++)
            s[i][i]=1;
    else if(type == 2)
            for(int i=0;i<a;i++)
            for(int j=0;j<b;j++)
            s[i][j]=1;
}

void Mat::clear(int type)
{   memset(s,0,sizeof(s));
         if(type==1)
            for(int i=0;i<min(sizei,sizej);i++)
            s[i][i]=1;
    else if(type == 2)
            for(int i=0;i<sizei;i++)
            for(int j=0;j<sizej;j++)
            s[i][j]=1;
}
void Mat::ReSize(int a,int b,int type)
{   sizei=a; sizej=b;
    memset(s,0,sizeof(s));
         if(type==1)
            for(int i=0;i<min(sizei,sizej);i++)
            s[i][i]=1;
    else if(type == 2)
            for(int i=0;i<sizei;i++)
            for(int j=0;j<sizej;j++)
            s[i][j]=1;
}
void Mat::Add(const Mat& B)
{   for(int i=0;i<sizei;i++)
        for(int j=0;j<sizej;j++)
            {s[i][j]=s[i][j]+B.s[i][j];
             s[i][j]%=mod;
            }
}
void Mat::Sub(const Mat& B)
{   for(int i=0;i<sizei;i++)
        for(int j=0;j<sizej;j++)
            {s[i][j]=s[i][j]-B.s[i][j];
             s[i][j]=(s[i][j]+mod)%mod;
            }
}
void Mat::CopyMat(const Mat& B)
{   sizei=B.sizei; sizej=B.sizej;
    for(int i=0;i<sizei;i++)
        for(int j=0;j<sizej;j++)
            s[i][j]=B.s[i][j];

}
void Mat::Multiply(const Mat &B)
{   Mat c(sizei,B.sizej,0) ;
    for(int i=0;i<sizei;i++)
        for(int k=0;k<sizej;k++)
        if (s[i][k]>0)
            for(int j=0;j<B.sizej;j++)
                {c.s[i][j]+=s[i][k]*B.s[k][j];
                 c.s[i][j]%=mod ;
                }
    *this = c;
}

void Mat::Er_work(int n)
{
    Mat e(sizei,sizej,1);
    while (n)
    {   if(n&1)
            e.Multiply(*this);
        n>>=1;
        Multiply(*this);
    }
    *this = e;
}

void Mat::solve(int p)
{
    Mat temp1 = *this, temp2 = *this;
    Mat e(sizei, sizej, 1);
    if(p == 1)
        return;
    else if(p&1)
    {
        temp1.Er_work(p);
        temp2.solve(p-1);
        temp1.Add(temp2);
    }
    else
    {
        temp1.Er_work(p>>1);
        temp1.Add(e);
        temp2.solve(p>>1);
        temp1.Multiply(temp2);
    }
    *this = temp1;
};

Mat ee,ans;


struct HASHMAP
{
    int head[HASH],next[HASH],size;
    int state[HASH];
    LL f[HASH];
    void init()
    {
        size=0;
        memset(head,-1,sizeof(head));
    }
    void push(int st,LL ans)
    {
        int h=st%HA;
        if(head[h]!=-1)
          {
              f[head[h]]+=ans;
              f[head[h]]%=mod;
              return;
          }
        state[size]=h;
        f[size]=ans;
        next[size]=head[h];
        head[h]=size++;
    }
}hm[2];

void shift(int cur)
{
    for(int i=0;i<hm[cur].size;i++)
         {hm[cur].state[i]<<=2;
          hm[cur].state[i]%=HA;
         }
}
inline int cp(int p,int i)
{
    return p&(~(3<<jz[i]));
}
inline int cp(int p,int i,int j)
{
    return p&(~(3<<jz[i]))&(~(3<<jz[j]));
}
inline int cp(int p,int i,int j,int k)
{
    return p&(~(3<<jz[i]))&(~(3<<jz[j]))&(~(3<<jz[k]));
}
inline int getp(int p,int i)
{
    return 3&(p>>jz[i]);
}
inline int pp(int i,int k)
{   return k<<jz[i];
}
inline int lp(int p,int j)
{   for (int it=j-2,cnt=1;;it--)
        {   int pi=getp(p,it);
            if (pi==1) cnt--;
            else if (pi==2) cnt++;
            if (cnt==0) return it;
        }
}
inline int rp(int p,int j)
{   for (int it=j+1,cnt=1;;it++)
        {   int pi=getp(p,it);
            if (pi==2) cnt--;
            else if (pi==1) cnt++;
            if (cnt==0) return it;
        }
}
void dp(int i,int j,int cur)
{

    for(int k=0;k<hm[cur].size;k++)
        {int s=hm[cur].state[k];
         LL data=hm[cur].f[k];
         int left=getp(s,j);
         int up=getp(s,j+1);
         if (left==0&&up==0)
            {if (j+1<m)
                {
                    hm[cur^1].push(s|pp(j,1)|pp(j+1,2),data);
                }
             continue;
            }
         if (left==0||up==0)
            {   int w=left+up;
                int tmp=cp(s,j,j+1);
                if (j+1<m) hm[cur^1].push(tmp|pp(j+1,w),data);
                hm[cur^1].push(tmp|pp(j,w),data);
                continue;
            }
         if (left==up)
            {   int it=(left==1)?rp(s,j+1):lp(s,j+1);
                hm[cur^1].push(cp(s,j,j+1,it)|pp(it,left),data);
                continue;
            }
//         if (left==1&&up==2)
//            {   if (i==ex&&j==ey) ans+=data;
//                continue;
//            }
        if (left==2&&up==1)
            {   hm[cur^1].push(cp(s,j,j+1),data);
                continue;
            }
        }


}

void init()
{
    ex=n-1; ey=m-1;
}
void solve()
{
    ee.ReSize(o,o,0);
    int cur;
    for(int i=0;i<HA;i++)
        if (id[i]!=-1)
        {cur=0;
         hm[cur].init();
         hm[cur].push(i,1);
            for(int j=0;j<m;j++)
            {
             hm[cur^1].init();
             dp(i,j,cur);
             cur^=1;
            }
         shift(cur);
         for(int ii=0;ii<hm[cur].size;ii++)
            ee.s[id[i]][id[hm[cur].state[ii]]]=hm[cur].f[ii];

        }


    ee.Er_work(n);
    ans.ReSize(1,o,0);
    ans.s[0][0]=1;
    ans.Multiply(ee);
    LL anss=0;
    for (int i=0;i<HA;i++)
     if (id[i]!=-1)
       {    if ((1<<jz[m])*2+(1<<jz[m-1])==i)
            {anss+=ans.s[0][id[i]];
             anss%=mod;
             //printf("~\n");
            }
       }
    printf("%I64d\n",anss*2%mod);


}
int tmp[6];
void prepared_jinzhi()
{   for (int i=0;i<=m;i++)
        jz[i]=i*2;
    memset(id,255,sizeof(id)); o=0;
    for (int i=0;i<HA;i++)
    {   int f=1;
        for (int j=0;j<=m;j++)
            {   tmp[j]=3&(i>>jz[j]);
                if (tmp[j]==3) {f=0; break;}
            }
        if (!f) continue;
        if (tmp[0]) continue;
        int s=0;
        for (int j=1;j<=m;j++)
            {
                if (tmp[j]==1) s++;
                if (tmp[j]==2) s--;
                if (s<0) f=0;
            }
        if (s) f=0;
        if (f) id[i]=o++;

    }

}
int main()
{
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        init();
        HA=1<<(m*2+2);
        prepared_jinzhi();
        if (m*n%2==1) {printf("%d\n",0);continue;}
        solve();
    }
    return 0;
}

//ural 1117
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
const int inf=0x3f3f3f3f;
typedef long long LL;
using namespace std;
LL s[41],l[41],a,b;
void pre()
{   l[0]=0; s[0]=0;
    for (int i=1;i<=40;i++)
        {   l[i]=(l[i-1]+s[i-1])*2;
            s[i]=s[i-1]+1;
        }
}

LL solve(LL x)
{   LL ans=0;
    while (x>1)
        {
            LL p=1,t=-1;
            while (p<=x) {p<<=1; t++;}
            p>>=1; t--;
            x-=p;
            if (x)ans+=(l[t]+s[t]*2);else ans+=(l[t]+s[t]);
        }
    return ans;
}
int main()
{
    pre();
    while (scanf("%I64d%I64d",&a,&b)!=EOF)
        printf("%I64d\n",abs(solve(b)-solve(a)));
}

//ural 1310
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <iostream>
#include <string>
#include <cstdlib>
#include <map>
#define pb push_back
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define MS(x, y) memset(x, y, sizeof(x))
#define FOR(i, x, y) for(int i=x; i<=y; i++)
#define rFOR(i, x, y) for(int i=x; i>=y; i--)
using namespace std;
const int maxn = 175;
struct bigint
{
    int s[maxn];

    bigint() {MS(s, 0);}
    bigint(int num) {*this = num;}
    bigint(const char* num){*this = num;}

    bigint operator = (const char* num)
    {
        MS(s, 0);
        if(num[0] == '-')
        {
            num = num + 1;
            s[0] = -1;
        }
        else s[0] = 1;
        while(num[0] == '0') num = num + 1;
        s[0] = s[0] * strlen(num);
        int len = abs(s[0]);
        FOR(i, 1, len) s[i] = num[len - i] - 48;
        return *this;
    }
    bigint operator = (int num)
    {
        char s[maxn];
        sprintf(s, "%d", num);
        *this = s;
        return *this;
    }

    string str() const
    {
        string res = "";
        FOR(i, 1, abs(s[0])) res = (char)(s[i] + 48) + res;
        if(res == "") return res = "0";
        if(s[0] < 0) res = '-' + res;
        return res;
    }

    bool operator < (const bigint& b) const
    {
        if(s[0] != b.s[0]) return s[0] < b.s[0];
        int len = abs(s[0]);
        rFOR(i, len, 1)
        if(s[i] != b.s[i])
            return (s[i] < b.s[i]) ^ (s[0] < 0);
        return false;
    }
    bool operator > (const bigint& b) const{return b < *this;}
    bool operator <= (const bigint& b) const{return !(b < *this);}
    bool operator >= (const bigint& b) const{return !(*this < b);}
    bool operator != (const bigint& b) const{return b < *this || *this < b;}
    bool operator == (const bigint& b) const{return !(b < *this) && !(*this < b);}

    friend bigint abs(bigint b)
    {
        b.s[0] = abs(b.s[0]);
        return b;
    }
    friend bigint _add(const bigint& a, const bigint& b)
    {
        bigint c;
        c.s[0] = max(a.s[0], b.s[0]);
        FOR(i, 1, c.s[0]) c.s[i] = a.s[i] + b.s[i];
        FOR(i, 1, c.s[0])
        if(c.s[i] >= 10)
        {
            c.s[i+1]++;
            c.s[i]-=10;
        }
        if(c.s[c.s[0]+1]) ++c.s[0];
        return c;
    }
    friend bigint _sub(const bigint& a, const bigint& b)
    {
        bigint c;
        c.s[0] = a.s[0];
        FOR(i, 1, c.s[0]) c.s[i] = a.s[i] - b.s[i];
        FOR(i, 1, c.s[0])
        if(c.s[i] < 0)
        {
            c.s[i+1]--;
            c.s[i] += 10;
        }
        while(!c.s[c.s[0]] && c.s[0]) --c.s[0];
        return c;
    }
    bigint operator + (const bigint& b) const
    {
        if(s[0] >= 0 && b.s[0] >= 0) return _add(*this, b);
        if(b.s[0] < 0) return *this - abs(b);
        if(s[0] < 0) return b - abs(*this);
    }
    bigint operator - (const bigint& b) const
    {
        if(s[0] >= 0 && b.s[0] >= 0)
        {
            bigint c;
            if(*this >= b) return _sub(*this, b);
            c = _sub(b, *this);
            c.s[0] = -c.s[0];
            return c;
        }
        if(b.s[0] < 0) return *this + abs(b);
        if(s[0] < 0)
        {
            bigint c;
            c = abs(*this) + b;
            c.s[0] = -c.s[0];
            return c;
        }
    }
    bigint operator * (const bigint& b) const
    {
        bigint c;
        c.s[0] = abs(s[0]) + abs(b.s[0]);
        FOR(i, 1, abs(s[0]))
        FOR(j, 1, abs(b.s[0]))
            c.s[i + j - 1] += s[i] * b.s[j];
        FOR(i, 1, c.s[0])
        {
            c.s[i+1] += c.s[i] / 10;
            c.s[i] %= 10;
        }
        while(!c.s[c.s[0]] && c.s[0]) --c.s[0];
        if((s[0] > 0) != (b.s[0] > 0)) c.s[0] = -c.s[0];
        return c;
    }
    bigint operator / (const bigint& _b) const
    {
        bigint c, t;
        bigint b = abs(_b);
        c.s[0] = abs(s[0]);
        rFOR(i, c.s[0], 1)
        {
            rFOR(j, t.s[0], 1) t.s[j + 1] = t.s[j];
            t.s[1] = s[i];
            if (t.s[t.s[0]+1])t.s[0]++;

            while(t >= b)
            {
                ++c.s[i];
                t -= b;
            }
        }
        while(!c.s[c.s[0]] && c.s[0]) --c.s[0];
        if((s[0] > 0) != (b.s[0] > 0)) c.s[0] = -c.s[0];
        return c;
    }
    bigint operator % (const bigint& _b) const
    {
        bigint c, t;
        bigint b = abs(_b);
        rFOR(i, abs(s[0]), 1)
        {
            rFOR(j, t.s[0], 1) t.s[j + 1] = t.s[j];
            t.s[1] = s[i];
            if (t.s[t.s[0]+1])t.s[0]++;

            while(t >= b) t -= b;
        }
        if((s[0] < 0)) t.s[0] = -t.s[0];
        return t;
    }

    bigint operator += (const bigint& b) {*this = *this + b;return *this;}
    bigint operator -= (const bigint& b) {*this = *this - b;return *this;}
    bigint operator *= (const bigint& b) {*this = *this * b;return *this;}
    bigint operator /= (const bigint& b) {*this = *this / b;return *this;}
    bigint operator %= (const bigint& b) {*this = *this % b;return *this;}

    friend bigint operator + (int& a, const bigint& b){return (bigint)a + b;}
    friend bigint operator - (int& a, const bigint& b){return (bigint)a - b;}
    friend bigint operator * (int& a, const bigint& b){return (bigint)a * b;}
    friend bigint operator / (int& a, const bigint& b){return (bigint)a / b;}
    friend bigint operator % (int& a, const bigint& b){return (bigint)a % b;}

    friend bigint operator <  (int& a, const bigint& b){return (bigint)a < b;}
    friend bigint operator <= (int& a, const bigint& b){return (bigint)a <=b;}
    friend bigint operator >  (int& a, const bigint& b){return (bigint)a > b;}
    friend bigint operator >= (int& a, const bigint& b){return (bigint)a >=b;}
    friend bigint operator == (int& a, const bigint& b){return (bigint)a ==b;}
    friend bigint operator != (int& a, const bigint& b){return (bigint)a !=b;}
};
istream& operator >> (istream &in, bigint& x)
{
    string s;
    in >> s;
    x = s.c_str();
    return in;
}
ostream& operator << (ostream &out, const bigint& x)
{
    out << x.str();
    return out;
}

using namespace std;
int l,m,k;
bigint x;
bigint dp[101][50];
void doit()
{
    cin>>x;x+=1;
    for (int z=0;z<k;z++)
        dp[0][z]=0;
    dp[0][0]=1;
    for (int i=1;i<=l;i++)
        {   for (int z=0;z<k;z++)
                dp[i][z]=0;
            for (int j=1;j<=m;j++)
            for (int z=0;z<k;z++)
                dp[i][(z+j)%k]+=dp[i-1][z];

        }

    int w=l,i,p=0;
    bool have=0;
    bigint tmp;
    while (w)
        {   for (i=1;i<=m;i++)
                {  tmp=dp[w-1][((p-i)%k+k)%k];
                   if (x<=tmp) break;else x-=tmp;
                }
            if (have) printf(" "); have=1;
            printf("%d",i);
            w--;
            p=((p-i)%k+k)%k;
        }
    printf("\n");
}

int main()
{   while (scanf("%d%d%d",&l,&m,&k)!=EOF) doit();
}
/*
3 10 4
213
*/

//ural 1577
//CONTINUE!
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
const int inf=0x3f3f3f3f;
const long long INF=1LL<<50;
using namespace std;
typedef long long LL;
typedef pair <int,double> PII;
int mod,n,m,t,tot;
#define N 2005
#define e 1000000007
int s[N][N],f[N][N];
char s1[N],s2[N];
void doit()
{   int la=strlen(s1),lb=strlen(s2);
    memset(f,0x3f,sizeof(f));
    f[0][0]=0;
    s[0][0]=1;
    for (int i=0;i<=la;i++)
    for (int j=0;j<=lb;j++)
        {   int tmp;
            if (i&&j&&s1[i-1]==s2[j-1])
                {
                    if (f[i][j]>f[i-1][j-1]+1)  {f[i][j]=f[i-1][j-1]+1; s[i][j]=s[i-1][j-1];}else
                    if (f[i][j]==f[i-1][j-1]+1) {s[i][j]=(s[i][j]+s[i-1][j-1])%e;}
                    continue; //!
                }
            if (i)
                 {if (f[i][j]>f[i-1][j]+1)  {f[i][j]=f[i-1][j]+1; s[i][j]=s[i-1][j];}else
                  if (f[i][j]==f[i-1][j]+1) {s[i][j]=(s[i][j]+s[i-1][j])%e;}
                 }
            if (j)
                 {if (f[i][j]>f[i][j-1]+1)  {f[i][j]=f[i][j-1]+1; s[i][j]=s[i][j-1];}else
                  if (f[i][j]==f[i][j-1]+1) {s[i][j]=(s[i][j]+s[i][j-1])%e;}
                 }
            //printf("%d %d %d %d\n\n\n",i,j,f[i][j],s[i][j]);
        }

    printf("%d\n",s[la][lb]);
}
int main()
{
    while (scanf("%s%s",s1,s2)!=EOF) doit();
}
/*
aa
ba

aa
ab
*/

//ural 1696
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
const int inf=0x3f3f3f3f;
const long long INF=1LL<<50;
using namespace std;
typedef long long LL;
typedef pair <int,double> PII;
#define N 202
int dp[2][N][N],a[N][N],b[N][N];
int n,m,mod;

void doit()
{   memset(dp,0,sizeof(dp));
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    for (int i=1;i<=m;i++)
         dp[1][i][0]=1;
    for (int i=1;i<n;i++)
    {memset(dp[(i&1)^1],0,sizeof(dp[(i&1)^1]));
     int o=i&1;
     for (int j=1;j<=m;j++)  a[j][0]=dp[o][j][0];
     for (int j=1;j<=m;j++)
     for (int k=1;k<=j-1;k++)a[j][k]=(dp[o][j][k]+a[j][k-1])%mod;

     for (int k=0;k<=m-1;k++)  b[k][k]=0;
     for (int k=0;k<=m-1;k++)
     for (int j=k+1;j<=m;j++)  b[j][k]=(dp[o][j][k]+b[j-1][k])%mod;

     for (int j=1;j<=m;j++)
     for (int k=0;k<=j-1;k++)
        {

                        dp[o^1][j][k]=(dp[o^1][j][k]+b[j][k])%mod;
            if (j-k!=1) dp[o^1][j][k]=(dp[o^1][j][k]+a[j][k])%mod;
        }
    }
    int ans=0;
    for (int j=1;j<=m;j++)
    for (int k=0;k<=j-1;k++)
        ans=(ans+dp[n&1][j][k])%mod;
    printf("%d\n",ans+1);
}
int main()
{
    while (scanf("%d%d%d",&n,&m,&mod)!=EOF) doit();
}

//ural 1552
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
const int inf=0x3f3f3f3f;
using namespace std;
const int N=27*27*27;
#define M 51
int f[M][4][N];
int dp[M][4][N];
char s[M];
int num[M+1],n;
int a[4];
inline int get(int a,int b)
{   if (a==0) a-=96;
    if (b==0) b-=96;
    return abs(a-b);
}
bool miniz(int &a,int b)
{
    if (b>a) return 0;
    a=b;
    return 1;
}
void print(int i,int j,int k)
{   if (!i) {for (int i=1;i<=num[0]+96;i++) printf("+"); printf("."); return;}

    int t1=f[i][j][k]/N,t2=f[i][j][k]%N;
    
    print(i-1,t1,t2);
    int x=t2;
    for (int p=3;p>=0;p--)
        if (p==t1) a[p]=num[i-1];
        else {a[p]=x%27; x/=27;}
    if (t1<j) for (int jj=1;jj<=j-t1;jj++) printf(">");
    if (t1>j) for (int jj=1;jj<=t1-j;jj++) printf("<");
    if (a[j]<num[i])  for (int jj=1;jj<=get(a[j],num[i]);jj++) printf("+");
    if (a[j]>num[i])  for (int jj=1;jj<=get(a[j],num[i]);jj++) printf("-");
    printf(".");
}
void doit()
{   for (int i=0;i<n;i++)
        num[i]=s[i]-'a'+1;
    memset(dp,0x3f,sizeof(dp));
    for (int i=0;i<4;i++)
        dp[0][i][0]=num[0]+96;

    for (int i=1;i<n;i++)
    for (int j=0;j<4;j++)
    for (int k=0;k<N;k++)
        if (dp[i-1][j][k]!=inf)
        {   int x=k;
            for (int p=3;p>=0;p--)
                if (p==j) a[p]=num[i-1];
                else {a[p]=x%27; x/=27;}

            for (int nj=0;nj<4;nj++)
                {   x=0;
                    for (int p=0;p<4;p++)
                        if (p!=nj) x=x*27+a[p];
                    if (miniz(dp[i][nj][x],dp[i-1][j][k]+abs(j-nj)+get(a[nj],num[i])))
                        {   //printf("%d %d %d ->%d %d %d\n",i-1,j,k,i,nj,x);
                            f[i][nj][x]=j*N+k;
                        }
                }
        }
    int ans=inf;
    for (int j=0;j<4;j++)
    for (int k=0;k<N;k++)
        ans=min(ans,dp[n-1][j][k]);
    for (int j=0;j<4;j++)
    for (int k=0;k<N;k++)
        if (ans==dp[n-1][j][k]) {print(n-1,j,k);
        return;}
}
int main()
{
    while (scanf("%s",s)!=EOF) {n=strlen(s);doit();}
}
//azazazazazazazazazazazazazazazazazazazaz

//ural 1655
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 505
#define eps 1e-6
#define MAX 1e7
typedef long long LL;
using namespace std;
const double tt=21600.0;
int n,nn,res;
double w,aa,tot;
double dp[N][N][2];
bool vis[N][N][2];
int from[N][N][2];
//dp[x][y][op];
//x,(x+1)%nn,(x+2)%nn,...,y
//op==0 end in x;
//op==1 end in y;
struct node{
    double qt,dt;
    int id;
    bool operator<(const node& oth)const
        {
            return qt<oth.qt;
        }
}a[N];
double get(int from,int to)
{    if (from>to) return tot-a[from].qt+a[to].qt;
             else return a[to].qt-a[from].qt;
}
void print(int x,int y,int op)
{   if (x==res&&y==res) return;
    int rr=from[x][y][op]/2,ii=from[x][y][op]%2;
    if (rr==0)
        {   print((x+1)%nn,y,ii);
            printf("%d\n",a[x].id);
        }
    if (rr==1)
        {   print(x,(y-1+nn)%nn,ii);
            printf("%d\n",a[y].id);
        }
}
double f(int x,int y,int op)
{
    if (vis[x][y][op]) return dp[x][y][op];
    double &ans=dp[x][y][op];
       int &fr=from[x][y][op];
    vis[x][y][op]=1;
    ans=MAX;
    int next;
    double ad1,ad2,ad3;


    next=(y-1+nn)%nn;
    ad3=get(next,y);
    if (op==0) ad1=get(x,y); else ad1=0;
    for (int i=0;i<2;i++)
                {if (i==0) ad2=get(x,next); else ad2=0;
                 double tmp=f(x,next,i);
                 if (tmp+ad2+ad3<=a[y].dt&&ans>tmp+ad1+ad2+ad3)
                    {ans=tmp+ad1+ad2+ad3;
                     fr=i+2;
                    }
                }
    next=(x+1)%nn;
    ad3=get(x,next);
    if (op==1) ad1=get(x,y); else ad1=0;
    for (int i=0;i<2;i++)
                {if (i==1) ad2=get(next,y); else ad2=0;
                 double tmp=f(next,y,i);
                 if (tmp+ad2+ad3<=a[x].dt&&ans>tmp+ad1+ad2+ad3)
                    {ans=tmp+ad1+ad2+ad3;
                     fr=i;
                    }
                }

    return ans;
}
void doit()
{   double x,y,z;
    w*=tt;
    for (int i=1;i<=n;i++)
        {
            scanf("%lf%lf%lf",&x,&y,&z);
            a[i].qt=x/w;
            a[i].dt=(y-1)/z+eps;
            a[i].id=i;
        }
    tot=360.0/w;
    a[0].qt=aa/w;
    a[0].dt=MAX; //imp锛�
    a[0].id=0;
    nn=n+1;
    sort(a,a+n+1);
    for (int i=0;i<=n;i++)
        if (a[i].id==0) {res=i;break;}
    memset(vis,0,sizeof(vis));

    for (int i=0;i<nn;i++)
    for (int j=0;j<2;j++)
        {
            vis[i][i][j]=1;
            dp[i][i][j]=(i==res)?0:MAX;
        }

    double ans=MAX,tmp;
    int an1,an2,an3;
    for (int i=0;i<=n;i++)
        {tmp=f(i,(i-1+nn)%nn,0);
         if (tmp<ans) {ans=tmp;an1=i;an2=(i-1+nn)%nn;an3=0;}
         tmp=f(i,(i-1+nn)%nn,1);
         if (tmp<ans) {ans=tmp;an1=i;an2=(i-1+nn)%nn;an3=1;}
        }

    if (ans+eps>=MAX) {printf("Impossible\n"); return;}
    printf("%.6lf\n",ans*60);
    print(an1,an2,an3);

}
int main()
{
    while (scanf("%lf%lf%d",&aa,&w,&n)!=EOF) doit();
}
/*
0 0.0278 3
280 46 100
90 16 100
180 61 100
*/

//ural 1739
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
const int inf=0x3f3f3f3f;
const long long INF=1LL<<50;
using namespace std;
typedef long long LL;
typedef pair <int,double> PII;
#define N 12
int a[N];
int tmp[N+1];
int n,tot;
int dp[1<<N][2][2],dp2[1<<N][2][2];
int from1[1<<N][2][2],from2[1<<N][2][2],from3[1<<N][2][2];
int sum[1<<N];

#define M 4097
int c1[M];
int c2[N][M];
int c3[N][M];
int c4[N][N][M];
int c5[N][M];
//c1
//c2[j] j-25%
//c3[j] j+10%
//c4[j1][j2] j1-25% j2+10%
//c5[j] j-25% +10%
bool minize(int &a,int b,int& a1,int b1)
{
    if (b>a) return 0;
    if (b==a&&b1>=a1) return 0;
    a=b;
    a1=b1;
    return 1;
}
void print(int left,int x1,int x2)
{   if (left==0) return;
    int f1=from1[left][x1][x2],f2=from2[left][x1][x2],f3=from3[left][x1][x2];
    int v1=f2/13,v2=f2%13;
    //printf("~~~~~%d %d %d %d %d %d\n",left,x1,x2,f1,f2,f3);

    if (f1>0)
        {   tmp[0]=0;
            for (int i=0;i<n;i++)
                if (f1&(1<<i))
                tmp[++tmp[0]]=i;
            printf("return %d",tmp[0]);
            for (int i=1;i<=tmp[0];i++)
                printf(" %d",tmp[i]+1);
                printf("\n");
        }
    if (v1) printf("dearomatize %d\n",v1);
    if (v2) printf("aromatize %d\n",v2);
    f3=left+f1-f3;
    if (f3>0)
        {   tmp[0]=0;
            for (int i=0;i<n;i++)
                if (f3&(1<<i))
                tmp[++tmp[0]]=i;
            printf("take %d",tmp[0]);
            for (int i=1;i<=tmp[0];i++)
                printf(" %d",tmp[i]+1);
                printf("\n");
        }
    f3=from3[left][x1][x2];
    print(f3,x1||v1,x2||v2);
}


void f(int left,int x1,int x2)
{   if (dp[left][x1][x2]!=-1) return;
    if (left==0) {dp[left][x1][x2]=0;dp2[left][x1][x2]=0;return;}

    int &re=dp[left][x1][x2],&re2=dp2[left][x1][x2];
    int &f1=from1[left][x1][x2],&f2=from2[left][x1][x2],&f3=from3[left][x1][x2];
    re=inf; re2=inf;
    int v,j;
    for (int i=1;i<=c1[0];i++)
        {j=c1[i];
         v=left^(left&j);
         f(v,x1,x2);
         if (minize(re,1+dp[v][x1][x2],re2,1+dp2[v][x1][x2]+((left&j)!=j)))
            {
                f1=j-(left&j);
                f2=0;
                f3=v;
            }

        }
    if (!x1)
    for (int k=0;k<n;k++)
    for (int i=1;i<=c2[k][0];i++)
        {j=c2[k][i];
         v=left^(left&j);
         f(v,1,x2);
         if (minize(re,1+dp[v][1][x2],re2,2+dp2[v][1][x2]+((left&j)!=j)))
            {   f1=j-(left&j);
                f2=(k+1)*13;
                f3=v;
            }
        }
    if (!x2)
    for (int k=0;k<n;k++)
    for (int i=1;i<=c3[k][0];i++)
        {j=c3[k][i];
         v=left^(left&j);
         f(v,x1,1);
         if (minize(re,1+dp[v][x1][1],re2,2+dp2[v][x1][1]+((left&j)!=j)))
            {   f1=j-(left&j);
                f2=(k+1);
                f3=v;

            }
        }
    if (!x1&&!x2)
    for (int k1=0;k1<n;k1++)
    for (int k2=0;k2<n;k2++)
    for (int i=1;i<=c4[k1][k2][0];i++)
        {j=c4[k1][k2][i];
         v=left^(left&j);
         f(v,1,1);
         if (minize(re,1+dp[v][1][1],re2,3+dp2[v][1][1]+((left&j)!=j)))
            {   f1=j-(left&j);
                f2=(k1+1)*13+(k2+1);
                f3=v;

            }
        }
    if (!x1&&!x2)
    for (int k=0;k<n;k++)
    for (int i=1;i<=c5[k][0];i++)
        {j=c5[k][i];
         v=left^(left&j);
         f(v,1,1);
         if (minize(re,1+dp[v][1][1],re2,3+dp2[v][1][1]+((left&j)!=j)))
            {   f1=j-(left&j);
                f2=(k+1)*13+(k+1);
                f3=v;

            }
        }
}
void doit()
{
    for (int i=0;i<n;i++) scanf("%d",&a[i]);
    tot=1<<n; tot--;

    memset(sum,0,sizeof(sum));
    for (int i=1;i<=tot;i++)
         {  int x=i&(-i);
            int t=int(log(double(x))/log(2.0)+eps);
            sum[i]=sum[i-x]+a[t];
         }
    memset(c1,0,sizeof(c1));
    memset(c2,0,sizeof(c2));
    memset(c3,0,sizeof(c3));
    memset(c4,0,sizeof(c4));
    memset(c5,0,sizeof(c5));
    for (int i=1;i<=tot;i++)
        if (sum[i]%256==0) {c1[++c1[0]]=i;}


    for (int j=0;j<n;j++)
        if (a[j]%4==0)
        {   int x;
            for (int i=1;i<=tot;i++)
                {   if (!(i&(1<<j))) continue;
                    x=sum[i]-a[j]+a[j]/4*3;
                    if (x%256==0) {c2[j][++c2[j][0]]=i;}
                }
        }
        for (int j=0;j<n;j++)
        if (a[j]%10==0)
        {   int x;
            for (int i=1;i<=tot;i++)
                {   if (!(i&(1<<j))) continue;
                    x=sum[i]-a[j]+a[j]/10*11;
                    if (x%256==0) {c3[j][++c3[j][0]]=i;}
                }
        }


    for (int j1=0;j1<n;j1++)
    for (int j2=0;j2<n;j2++)
    if (j1!=j2)
        if ((a[j1]*15+a[j2]*22)%20==0)
        {   int x;
            for (int i=1;i<=tot;i++)
                {   if (!(i&(1<<j1)))continue;
                    if (!(i&(1<<j2)))continue;
                    x=sum[i]-a[j1]-a[j2]+(a[j1]*15+a[j2]*22)/20;
                    if (x%256==0) {c4[j1][j2][++c4[j1][j2][0]]=i;}
                }
        }
    for (int j=0;j<n;j++)
        if (a[j]%40==0)
        {   int x;
            for (int i=1;i<=tot;i++)
                {   if (!(i&(1<<j))) continue;
                    x=sum[i]-a[j]+a[j]/40*33;
                    if (x%256==0) {c5[j][++c5[j][0]]=i;}
                }
        }
    memset(dp,255,sizeof(dp));
    f(tot,0,0);
    if (dp[tot][0][0]==inf) {printf("IMPOSSIBLE\n"); return;}
    if (dp2[tot][0][0]>20000) {printf("IMPOSSIBLE\n"); return;}
    printf("%d\n",dp2[tot][0][0]);
    print(tot,0,0);
}
int main()
{
    while (scanf("%d",&n)!=EOF) doit();
}
/*
2
40 223
*/

//ural 1895
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
const int inf=0x3f3f3f3f;
const long long INF=1LL<<50;
using namespace std;
typedef long long LL;
typedef pair <int,double> PII;
#define N 1005
#define M 55
#define M2 110
int n,X,K,o;
int f[M2][M][M],from1[M2][M][M],from2[M2][M][M];;
int t[M],ans1[M],ans2[M];
int num[M2];

int vis[N],have[N];

void print(int an1,int an2,int an3)
{   if (an1==0) return;
    int t1=from1[an1][an2][an3],t2=from2[an1][an2][an3];
    for (int i=t1+1;i<=an2;i++)
        ans1[i]=an1;
    for (int i=t2+1;i<=an3;i++)
        ans2[i]=an1;
    print(an1-1,t1,t2);

}
void doit()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
        scanf("%d",&t[i]); t[n+1]=-1;
    memset(vis,0,sizeof(vis));
//    for (int i=0;i<t[n];i++)
//        num[++o]=i;
    for (int i=1;i<=n;i++)
        {int x=t[i]-1;
         while (vis[x]&&x) x--; vis[x]=1;
         x--;
         if (x<0) continue;
         while (vis[x]&&x) x--; vis[x]=1;
        }
    o=0;
    for (int i=0;i<t[n];i++)
         if (vis[i]) {num[++o]=i;vis[i]=o;}
    int lx=1,x=1;

    for (int i=1;i<t[n];i++)
        {   while (t[x]==i) x++;
            have[i]=have[i-1]+x-lx;
            lx=x;
        }
//    for (int i=1;i<=o;i++)
//    printf("%d %d %d\n",i,num[i],have[num[i]]);

    memset(f,0x3f,sizeof(f));
    f[0][0][0]=0;

    for (int i=1;i<=o;i++)
    for (int j=0;j<=n;j++)
    for (int k=0;k<=j;k++)
        {   if (j<have[num[i]]||k<have[num[i]]) continue;
            if (f[i][j][k]>f[i-1][j][k])
                    {
                        f[i][j][k]=f[i-1][j][k];
                        from1[i][j][k]=j;
                        from2[i][j][k]=k;
                    }
            for (int nk=k;nk<=j;nk++)
            {   if (nk-k>K)break;
                int left=K-(nk-k);
                for (int use=0;use<=left;use++)
                    {    int nj=j+use;
                         if (nj>n) nj=n;
                         if (num[i]+X<t[nj]) break;

                         if (f[i][nj][nk]>f[i-1][j][k]+1)
                            {f[i][nj][nk]=f[i-1][j][k]+1;
                             from1[i][nj][nk]=j;
                             from2[i][nj][nk]=k;
                            }
                    }
             }

        }

    if (f[o][n][n]==inf) {printf("%d\n",-1); return;}
    printf("%d\n",f[o][n][n]);

    print(o,n,n);
    for (int i=1;i<=n;i++)
        printf("%d %d\n",num[ans1[i]],num[ans2[i]]);
}

int main()
{
    while (scanf("%d%d",&X,&K)!=EOF) doit();
}
/*
10 2
3
2 16 25
*/

//ural 1776
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
const int inf=0x3f3f3f3f;
const long long INF=1LL<<50;
using namespace std;
typedef long long LL;
typedef pair <int,double> PII;
#define N 402
double dp[N][N],sum[N][N];
int n;
int main()
{   memset(dp,0,sizeof(dp));
    memset(sum,0,sizeof(sum));

    dp[0][0]=1;
    for (int i=0;i<=400;i++)
        sum[0][i]=1;
    for (int i=1;i<=400;i++)
    {      for (int k=1;k<=i;k++)
           {   int t=max(k-1,i-k)+1;
               for (int j=1;j<=t;j++)
                dp[i][j]+= (dp[k-1][j-1] * sum[i-k][j-1]+
                            sum[k-1][j-1]*  dp[i-k][j-1]-
                            dp[k-1][j-1] *  dp[i-k][j-1])/i;
           }
           for (int j=1;j<=400;j++)
                sum[i][j]=sum[i][j-1]+dp[i][j];
    }
    while (scanf("%d",&n)!=EOF)
        {   n-=2;
            double ans=0;
            for (int i=1;i<=n;i++)
                ans+=dp[n][i]*i;
            printf("%.6lf\n",ans*10);
        }
}


用代码解决这个问题The program committee of the school programming contests, which are often held at the Ural State University, is a big, joyful, and united team. In fact, they are so united that the time spent together at the university is not enough for them, so they often visit each other at their homes. In addition, they are quite athletic and like walking. Once the guardian of the traditions of the sports programming at the Ural State University decided that the members of the program committee spent too much time walking from home to home. They could have spent that time inventing and preparing new problems instead. To prove that, he wanted to calculate the average distance that the members of the program committee walked when they visited each other. The guardian took a map of Yekaterinburg, marked the houses of all the members of the program committee there, and wrote down their coordinates. However, there were so many coordinates that he wasn't able to solve that problem and asked for your help. The city of Yekaterinburg is a rectangle with the sides parallel to the coordinate axes. All the streets stretch from east to west or from north to south through the whole city, from one end to the other. The house of each member of the program committee is located strictly at the intersection of two orthogonal streets. It is known that all the members of the program committee walk only along the streets, because it is more pleasant to walk on sidewalks than on small courtyard paths. Of course, when walking from one house to another, they always choose the shortest way. All the members of the program committee visit each other equally often. Input The first line contains the number n of members of the program committee (2 ≤ n ≤ 105). The i-th of the following n lines contains space-separated coordinates xi, yi of the house of the i-th member of the program committee (1 ≤ xi, yi ≤ 106). All coordinates are integers. Output Output the average distance, rounded down to an integer, that a member of the program committee walks from his house to the house of his colleague.
05-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值