zoukankan      html  css  js  c++  java
  • The 2017 ACM-ICPC Asia Beijing Regional Contest

    传送门

    C - Graph

    题意:
    给出一个(n)个点(m)条边的无向图。现在有多组询问,每组询问给出区间([l,r]),问区间([l,r])中有多少点对是连通的。

    思路:

    • 若考虑只有一组询问的情况,那么显然我们直接用并查集搞搞就行,复杂度为(O(mlogn))
    • 多组询问直接暴力上复杂度显然不够,所以现在有一种新姿势:回滚莫队。
    • 这个题的特点:多组区间询问,不带修改,那么我们就可以考虑莫队。
    • 但是区间端点移动时可能会涉及到撤销操作,但是对于并查集而言,我们不能直接从中间撤销。
    • 所以回滚莫队搞一下即可,就左端点滚过去,更新完后滚回来同时撤销刚才的操作即可。

    我们分块时按照点的度数来分块,本质上是按边的个数来划分,使得每一个块中边的个数之和约为(sqrt{2m})
    代码如下:

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    // #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 50000 + 5, M = 1e5 + 5;
    
    int n, m, q, blo;
    int d[N], f[N], in[N], rb[N], sz[N];
    int sta[N], top;
    int res;
    struct Edge{
    	int v, next;
    }e[N << 1];
    int head[N], tot;
    void adde(int u, int v) {
    	e[tot].v = v; e[tot].next = head[u]; head[u] = tot++;
    }
    int ans[M];
    struct Query{
    	int l, r, id;
    	bool operator < (const Query &A) const {
    		if(in[l] != in[A.l]) return in[l] < in[A.l];
    		return r < A.r;
    	}
    }Q[M];
    int find(int x) {
    	return f[x] == x ? f[x] : find(f[x]);
    }
    void Union(int x, int y, int op) {
    	int fx = find(x), fy = find(y);
    	if(fx == fy) return;
    	if(sz[fx] > sz[fy]) {
    		swap(x, y); swap(fx, fy);
    	}
    	res += sz[fx] * sz[fy];
    	f[fx] = fy;
    	sz[fy] += sz[fx];
    	if(!op) sta[++top] = fx;
    }
    void cancel() {
    	while(top) {
    		int u = sta[top--];
    		sz[f[u]] -= sz[u];
    		res -= sz[f[u]] * sz[u];
    		f[u] = u;
    	}
    }
    void run() {
    	cin >> n >> m >> q;
    	for(int i = 1; i <= n; i++) d[i] = 0, head[i] = -1;
    	tot = top = 0;
    	for(int i = 1; i <= m; i++) {
    		int u, v; cin >> u >> v;
    		adde(u, v); adde(v, u);
    		++d[u]; ++d[v];
    	}
    	int totd = 0;
    	int blo = sqrt(2 * m + 0.5) + 1;
    	for(int i = 1; i <= n; i++) {
    		totd += d[i];
    		in[i] = totd / blo;
    		rb[in[i]] = i;
    	}
    	for(int i = 1; i <= q; i++) {
    		cin >> Q[i].l >> Q[i].r;
    		Q[i].id = i;
    	}
    	sort(Q + 1, Q + q + 1);
    	int b = -1, L, R;
    	for(int i = 1; i <= q; i++) {
    		int l = Q[i].l, r = Q[i].r, id = Q[i].id;
    		if(b != in[l]) {
    			b = in[l];
    			L = R = rb[b];
    			res = 0;
    			for(int j = 1; j <= n; j++) f[j] = j, sz[j] = 1;
    		}
    		while(R < r) {
    			for(int j = head[++R]; j != -1; j = e[j].next) {
    				int v = e[j].v;
    				if(v > L && v <= r) Union(R, v, 1);
    			}
    		}
    		for(L = min(r, L); L >= l; L--) {
    			for(int j = head[L]; j != -1; j = e[j].next) {
    				int v = e[j].v;
    				if(v >= l && v <= r) Union(L, v, 0);
    			}
    		}
    		ans[id] = res;
    		cancel(); 
    		L = rb[b];
    	}
    	for(int i = 1; i <= q; i++) cout << ans[i] << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    
    

    E - Cats and Fish

    模拟题意即可。

    F - Secret Poems

    模拟。

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define REP(i,a,b) for(register int i=(a); i<(b); i++)
    #define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    
    char mtx[107][107];
    char st[107*107];
        int n;
    inline char rc() {
        static char c; do c=getchar(); while(c<=' ');
        return c;
    }
    
    inline void getst1() {
        int x=0,y=0;
    int chn=0;
        #define U() do{x--;st[chn++]=mtx[x][y];}while(0)
        #define D() do{x++;st[chn++]=mtx[x][y];}while(0)
        #define L() do{y--;st[chn++]=mtx[x][y];}while(0)
        #define R() do{y++;st[chn++]=mtx[x][y];}while(0)
        #define RU() do{y++;x--;st[chn++]=mtx[x][y];}while(0)
        #define DL() do{x++;y--;st[chn++]=mtx[x][y];}while(0)
            st[chn++]=mtx[x][y];
            if(n%2==0) {
                REP(i,1,n) {
                    if((i&1) ==1) {
                        R(); REP(j,0,i)DL();
                    } else {
                        D(); REP(j,0,i)RU();
                    }
                }
                PERE(i,n-2,0) {
                    if((i&1)==0) {
                        R(); REP(j,0,i)RU();
                    } else {
                        D(); REP(j,0,i)DL();
                    }
                }
            } else {
                REP(i,1,n) {
                    if((i&1)==1) {
                        R(); REP(j,0,i)DL();
                    } else {
                        D(); REP(j,0,i)RU();
                    }
                }
                PERE(i,n-2,0) {
                    if((i&1)==1) {
                        D(); REP(j,0,i)DL();
                    } else {
                        R(); REP(j,0,i)RU();
                    }
                }
            }
            st[chn]=0;
            #undef U
            #undef D
            #undef L
            #undef R
            #undef RU
            #undef DL
    }
    inline void writest() {
        int x=0,y=0;
        int chn=0;
        #define WR() do{mtx[x][y]=st[chn++];}while(0)
        #define R() do{y++;WR();}while(0)
        #define L() do{y--;WR();}while(0)
        #define D() do{x++;WR();}while(0)
        #define U() do{x--;WR();}while(0)
        WR();
        REP(i,1,n)R();
        int k=0;
        PERE(i,n-1,0) {
            if(k==0) {
                REP(j,0,i) D();
                k++; i++;
            } else if(k==1){
                REP(j,0,i) L();
                k++;
            } else if(k==2){
                REP(j,0,i) U();
                k++; i++;
            } else if(k==3){
                REP(j,0,i) R();
                k=0;
            }
        }
    }
    int main() {
        //ios::sync_with_stdio(false);
        //cin.tie(0); cout.tie(0);
        //cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        while(~scanf("%d", &n)) {
            REP(i,0,n)REP(j,0,n) mtx[i][j]=rc();
    
    
            getst1();
            writest();
    
            REP(i,0,n) {
                REP(j,0,n) {
                    putchar(mtx[i][j]);
                }
                putchar('
    ');
            }
        }
        return 0;
    }
    

    G - Liaoning Ship’s Voyage

    BFS+判断线段相交。

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define REP(i,a,b) for(register int i=(a); i<(b); i++)
    #define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
    #else
      #define dbg(...) (void)0
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    
    inline char gch() {
        static char x; do x=getchar(); while(x<=' ');
        return x;
    }
    
    #define EPS 1e-6
    inline int dcmp(double x) {
        if(fabs(x)<EPS) {
            return 0;
        }
        return x<0?-1:1;
    }
    
    struct Point {
        double x,y;
    };
    inline Point operator-(const Point&l, const Point &r) {
        return (Point){l.x-r.x, l.y-r.y};
    }
    
    Point sjx[3];
    char mp[27][27];
    int dis[27][27];
    int n;
    
    inline double cross(Point a, Point b) {
        return a.x*b.y-a.y*b.x;
    }
    
    inline double dot(Point a, Point b) {
        return a.x*b.x+a.y*b.y;
    }
    
    bool segpsec(Point a,Point b,Point c,Point d)
    {
        int d1=dcmp(cross(b-a,c-a)); //b-a, c-a
        int d2=dcmp(cross(b-a,d-a)); //b-a d-a
        int d3=dcmp(cross(d-c,a-c)); //d-c a-c
        int d4=dcmp(cross(d-c,b-c)); //d-c b-c
        return (d1^d2) == -2 && (d3^d4) == -2;
    }
    
    bool onseg(Point a, Point b, Point p) {
         return dcmp(cross(p-a,b-a)) == 0 && dcmp(dot(p-a,p-b)) <= 0;
    }
    
    bool segsec(Point a,Point b,Point c,Point d)
    {
        if (segpsec(a,b,c,d)) return true;
        return onseg(a,b,c) || onseg(a,b,d) || onseg(c,d,a) || onseg(c,d,b);
    }
    
    Point llsec(Point a, Point b, Point c, Point d) {
        double a1=cross(d-c,a-c);
        double a2=cross(d-c,b-c);
        return (Point){(a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1 )};
    }
    
    inline bool in(int x, int y) {
        Point k=(Point){x,y};
        int sgn1=dcmp(cross(sjx[0]-sjx[1],k-sjx[1]));
        int sgn2=dcmp(cross(sjx[1]-sjx[2],k-sjx[2]));
        int sgn3=dcmp(cross(sjx[2]-sjx[0],k-sjx[0]));
        if(sgn1==sgn2 && sgn2==sgn3) return true;
        return false;
    }
    
    inline bool in2(double x, double y) {
        Point k=(Point){x,y};
        int sgn1=dcmp(cross(sjx[0]-sjx[1],k-sjx[1]));
        int sgn2=dcmp(cross(sjx[1]-sjx[2],k-sjx[2]));
        int sgn3=dcmp(cross(sjx[2]-sjx[0],k-sjx[0]));
        if(sgn1==sgn2 && sgn2==sgn3) return true;
        return false;
    }
    
    inline void draw() {
        REP(i,0,n) REP(j,0,n) {
            if(in(i,j)) {
                mp[i][j]='#';
            }
        }
    }
    struct node {
        int x,y;
    };
    queue<node> q;
    inline void bfs() {
        if(mp[0][0]=='#') {
            puts("-1");
            return;
        }
        REP(i,0,n) REP(j,0,n) {
            dis[i][j]=0x3f3f3f3f3f;
        }
        dis[0][0]=0;
        q.push((node){0,0});
        const int dx[]={0,1,1,1,0,-1,-1,-1};
        const int dy[]={1,1,0,-1,-1,-1,0,1};
        while(!q.empty()) {
            node now=q.front(); q.pop();
            REP(i,0,8) {
                node nxt=(node){now.x+dx[i], now.y+dy[i]};
                if(nxt.x<n&&nxt.x>=0 &&
                    nxt.y<n && nxt.y>=0 &&
                    mp[nxt.x][nxt.y]=='.' &&
                    dis[nxt.x][nxt.y]>dis[now.x][now.y]+1) {
                    Point z1=(Point){now.x,now.y};
                    Point z2=(Point){nxt.x,nxt.y};
                    bool go1=segpsec(z1,z2,sjx[0],sjx[1]);
                    bool go2=segpsec(z1,z2,sjx[1],sjx[2]);
                    bool go3=segpsec(z1,z2,sjx[2],sjx[0]);
                    if(go1 || go2 || go3) continue;
                    Point ps[3]; int pn=0;
                    if(segsec(z1,z2,sjx[0],sjx[1]))
                        if(dcmp(cross(z2-z1,sjx[0]-sjx[1]))!=0) {ps[pn++]=llsec(z1,z2,sjx[0],sjx[1]);}
                    if(segsec(z1,z2,sjx[1],sjx[2]))
                        if(dcmp(cross(z2-z1,sjx[1]-sjx[2]))!=0) {ps[pn++]=llsec(z1,z2,sjx[1],sjx[2]);}
                    if(segsec(z1,z2,sjx[2],sjx[0]))
                        if(dcmp(cross(z2-z1,sjx[2]-sjx[0]))!=0) {ps[pn++]=llsec(z1,z2,sjx[2],sjx[0]);}
                    if(pn==3) continue;
                    if(pn==2 && in2((ps[0].x+ps[1].x)/2 , (ps[0].y+ps[1].y)/2)) {
                        continue;
                    }
                    dis[nxt.x][nxt.y]=dis[now.x][now.y]+1;
                    q.push(nxt);
                }
            }
        }
        if(dis[n-1][n-1]<0x3f3f3f3f) {
            printf("%d
    ", dis[n-1][n-1]);
        } else {
            puts("-1");
        }
    }
    
    int main() {
        //ios::sync_with_stdio(false);
        //cin.tie(0); cout.tie(0);
        //cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        while(~scanf("%d", &n)) {
            REP(i,0,3) scanf("%lf%lf", &sjx[i].x, &sjx[i].y);
            //REP(i,0,n+1) REP(j,0,n+1) mp[i][j]='.';
            REP(i,0,n) REP(j,0,n) {
                mp[j][n-1-i]=gch();
            }
    
            draw();
            #ifdef Local
            REP(i,0,n) {
                REP(j,0,n) {
                    putchar(mp[j][n-1-i]);
                }
                putchar('
    ');
            }
            #endif
            bfs();
        }
        return 0;
    }
    

    H - Puzzle Game

    题意:
    给出一个(n*m)的矩阵,每个位置有对应权值,可能为负。
    现在给定一个(p),能替换一个位置的权值。问最后的最大子矩阵最小权值为多少。

    思路:

    • 考虑枚举每个位置进行修改,然后快速维护答案;
    • 显然修改操作只会影响包含当前位置的最大子矩阵,我们还需要快速求出其余位置的最大子矩阵。
    • 那么我们预处理出(up,down,left,right)表示四个方向的最大子矩阵,就可以快速求出不包含当前点的答案了。这可以直接(O(n^3))预处理。
    • 包含当前位置的最大子矩阵,我们可以任选一个最大子矩阵,然后在其内部枚举即可。
    • 正确性?
    • 对于与其重合的最大子矩阵,我们枚举时会考虑到交点;否则,其余的最大子矩阵,我们求出其余方向的矩阵时会考虑到。

    简单说就直接考虑包含和不包含两种情况,不包含情况预处理出来,包含的情况直接考虑最大子矩阵即可。
    预处理可以枚举两行、两列然后求最大子序列和。
    详见代码:

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    // #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 155;
    
    int n, m, p;
    int a[N][N];
    int Up[N], Down[N], Left[N], Right[N];
    int u, d, l, r;
    int sum[N], res[N];
    
    int calc() {
    	int tot = -INF;
    	for(int i = 1; i <= n; i++) {
    		for(int j = 1; j <= m; j++) sum[j] = 0;
    		for(int j = i; j <= n; j++) {
    			for(int k = 1; k <= m; k++) sum[k] += a[j][k];
    			int p = 0;
    			for(int k = 1; k <= m; k++) {
    				res[k] = res[k - 1] + sum[k];
    				if(res[k] - res[p] > tot) {
    					tot = res[k] - res[p];
    					u = i, d = j, l = p + 1, r = k;
    				}
    				if(res[k] < res[p]) p = k;
    			}
    		}
    	}
    	dbg(u, d, l, r, tot);
    	return tot;
    }
    
    void calc1() {
    	for(int i = 1; i <= n; i++) {
    		for(int j = 1; j <= m; j++) sum[j] = 0;
    		for(int j = i; j <= n; j++) {
    			int tot = -INF;
    			for(int k = 1; k <= m; k++) sum[k] += a[j][k];
    			int p = 0;
    			for(int k = 1; k <= m; k++) {
    				res[k] = res[k - 1] + sum[k];
    				if(res[k] - res[p] > tot) {
    					tot = res[k] - res[p];
    					Down[i] = max(Down[i], tot);
    					Up[j] = max(Up[j], tot);
    				}
    				if(res[k] < res[p]) p = k;
    			}
    		}
    	}
    	for(int i = 2; i <= n; i++) Up[i] = max(Up[i], Up[i - 1]);
    	for(int i = n - 1; i >= 1; i--) Down[i] = max(Down[i], Down[i + 1]);
    }
    
    void calc2() {
    	for(int i = 1; i <= m; i++) {
    		for(int j = 1; j <= n; j++) sum[j] = 0;
    		for(int j = i; j <= m; j++) {
    			int tot = -INF;
    			for(int k = 1; k <= n; k++) sum[k] += a[k][j];
    			int p = 0;
    			for(int k = 1; k <= n; k++) {
    				res[k] = res[k - 1] + sum[k];
    				if(res[k] - res[p] > tot) {
    					tot = res[k] - res[p];
    					Left[j] = max(Left[j], tot);
    					Right[i] = max(Right[i], tot);
    				}
    				if(res[k] < res[p]) p = k;
    			}
    		}
    	}
    	for(int i = 2; i <= m; i++) Left[i] = max(Left[i], Left[i - 1]);
    	for(int i = m - 1; i >= 1; i--) Right[i] = max(Right[i], Right[i + 1]);
    }
    
    void run() {
    	for(int i = 1; i <= n; i++) {
    		for(int j = 1; j <= m; j++) {
    			cin >> a[i][j];
    		}
    	}
    	for(int i = 0; i <= n + 1; i++) Up[i] = Down[i] = -INF;
    	for(int i = 0; i <= m + 1; i++) Left[i] = Right[i] = -INF;
     	int Max = calc();
    	calc1();
    	calc2();
    	dbg(Up[1], Right[3], Down[2], Left[2]);
    	int ans = Max;
    	for(int i = u; i <= d; i++) {
    		for(int j = l; j <= r; j++) {
    			if(a[i][j] <= p) continue;
    			ans = min(ans, max(Max - a[i][j] + p, max(Up[i - 1], 
    				max(Down[i + 1], max(Left[j - 1], Right[j + 1])))));
    		}
    	}
    	cout << ans << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        while(cin >> n >> m >> p) run();
        return 0;
    }
    
    

    J - Pangu and Stones

    题意:
    给出(n)堆石子,每堆石子有(a_i)个。现在每次可以选择(l)~(r)堆的石子进行合并,问最后合并为一堆石子的最小代价为多少;不能合并为一堆则输出(-1)

    思路:

    • 定义(dp(l,r,k))表示考虑将区间([l,r])分为(k)堆的最小代价。
    • 如果我们已经确定了一种划分方式,那么直接合并起来,代价为(sum_r-sum_{l-1})
    • 假设现在(k=1),显然我们要将([l,r])个数的堆合并为一堆,注意到对于所有的(x)堆合并为一堆,我们可以将其划分为(x-1)堆和(1)堆的合并;
    • (k>1),此时不考虑合并,考虑通过一种最小的代价将其划分为(k)堆,同样地,我们通过枚举中间点,然后将序列划分为(k-1)(1)堆,这能覆盖到所有的情况。

    所以(dp)的状态转移方程为:

    [left{ egin{aligned} &dp[i][j][1]=min{dp[i][k][x-1]+dp[k+1][j][1]+sum_{j}-sum_{i-1}}\ &dp[i][j][x]=min{dp[i][k][x-1]+dp[k+1][j][1],x>1} end{aligned} ight. ]

    详见代码:(感觉说不清楚QAQ)

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    // #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 105;
    
    int n, l, r;
    int a[N], sum[N];
    int dp[N][N][N];
    
    void run() {
    	for(int i = 1; i <= n; i++) {
    		cin >> a[i];
    		sum[i] = sum[i - 1] + a[i];
    	}
    	for(int i = 1; i <= n; i++) 
    		for(int j = 1; j <= n; j++) 
    			for(int k = 0; k <= n; k++) 
    				dp[i][j][k] = INF;	
    	for(int i = 1; i <= n; i++) {
    		dp[i][i][1] = 0;
    	}
    	for(int len = 2; len <= n; len++) {
    		for(int i = 1; i + len - 1 <= n; i++) {
    			int j = i + len - 1;
    			for(int k = i; k < j; k++) {
    				for(int t = l - 1; t <= r - 1; t++) {
    					if(k - i + 1 >= t)
    						dp[i][j][1] = min(dp[i][j][1], dp[i][k][t] + dp[k + 1][j][1] + sum[j] - sum[i - 1]);
    				}
    			}
    			for(int t = 2; t <= j - i + 1; t++) {
    				for(int k = i; k < j; k++) {
    					if(k - i + 1 >= t - 1)
    					dp[i][j][t] = min(dp[i][j][t], dp[i][k][t - 1] + dp[k + 1][j][1]);
    				}
    			}
    		}
    	}
    	if(dp[1][n][1] == INF) dp[1][n][1] = 0;
    	pt(dp[1][n][1]);
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        while(cin >> n >> l >> r) run();
        return 0;
    }
    
    
  • 相关阅读:
    Linux Enterprise Cluster NOtes Ch4 同步:ssh和rsync
    e805上不安装中文外挂支持中文,很简单而且实用
    ARM的一些概念性问题
    C#调用WORD处理的小项目 转
    ASP.NET面试题
    .net清除cookie代码|.net为什么不能清除cookie|.net cookie 过期代码
    c#字符串转数字的函数|c#字符串转数字的无错函数|c#字符串转数字的最好函数
    Wiki简介
    new 和override 重写区别
    禁用IE的后退按钮|显示网页已过期|几种语言的实现方法|c#|javascript|html
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/11723461.html
Copyright © 2011-2022 走看看