zoukankan      html  css  js  c++  java
  • 5 November

    拓扑排序

    for (int i=1; i<=n; ++i) if (!ind[i]) q.push(i);
    while (!q.empty()) {
    	int now=q.top(); q.pop(); printf("%d ", now);
    	for (int k=head[now]; k; k=nex[k]) 
    		if (--ind[to[k]]==0) q.push(to[k]);
    }
    

    神奇の背包 DP

    现有 (N) 个物品和容积为 (M) 的背包. 物品的体积分别为 (V_1, V_2, ..., V_N). 求不选取物品 (i) 时, 装满背包的方案数量.

    (f(n, V)) 为正向枚举的背包, (g(n, V)) 为反向枚举的背包, 则方案数为 (displaystyle sum_{i=1}^{n}sum_{j=0}^{m} f(i-1, j)cdot g(i+1, m-j)).

    本次错误在于没有搞明白1维和2维背包的代码异同点:1维背包已经无需直接赋值,2维背包还是需要 (f(i, j)=f(i-1, j)) 的。

    #include <cstdio>
    
    int n, m, w[1003], f[1003][10003], g[1003][10003], ans;
    
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i=1; i<=n; ++i) scanf("%d", &w[i]);
    	f[0][0]=1;
    	for (int i=1; i<=n; ++i) {
    		for (int j=m; j>=w[i]; --j) f[i][j]=(f[i-1][j]+f[i-1][j-w[i]])%1014;
    		for (int j=w[i]-1; ~j; --j) f[i][j]=f[i-1][j]; // (*)
    	}
    	g[n+1][0]=1;
    	for (int i=n; i; --i) {
    		for (int j=m; j>=w[i]; --j) g[i][j]=(g[i+1][j]+g[i+1][j-w[i]])%1014;
    		for (int j=w[i]-1; ~j; --j) g[i][j]=g[i+1][j]; // (*)
    	}
    	for (int i=1; i<=n; ++i) {
    		ans=0;
    		for (int j=0; j<=m; ++j) ans=(ans+f[i-1][j]*g[i+1][m-j])%1014;
    		printf("%d ", ans);
    	}
    	return 0;
    }
    

    Sequence

    给出数列 ({A_n}), 修改最少的元素, 使得数列 ({A_n}) 成为一个公差为 1 的等差数列.

    预处理成数列 ({A_n-n}) 即可极大简化本题解法.

  • 相关阅读:
    BZOJ3672/UOJ7 [Noi2014]购票
    POJ3718 Facer's Chocolate Dream
    BZOJ1453:[WC]Dface双面棋盘
    BZOJ2957:楼房重建
    AtCoder Grand Contest 009 D:Uninity
    BZOJ2877:[NOI2012]魔幻棋盘
    BZOJ3065:带插入区间K小值
    BZOJ3489:A simple rmq problem
    浅谈主席树
    AtCoder Regular Contest 080 E:Young Maids
  • 原文地址:https://www.cnblogs.com/greyqz/p/11807418.html
Copyright © 2011-2022 走看看