D - Circuit Counting dp求方案数

题目:https://vjudge.z180.cn/contest/425090#problem/D
题意: 用n个向量组成不同的几个向量,是的他们的和是零。

分析: 可以用dp来求方案数
f (i, j, k) 表示用前i个向量他们的和为(j, k ) 的方案的数量。
那么由定义可知 f(0, 0, 0) 是1, 但是题目要求这个不算是一种方案,所以最终要减掉。
把 f(i, j, k)分成两个集合, 第一个是包含第i个向量的方案数,另一个是不包含i的方案数, 则f(i, j, k) = f (i - 1, j - x, k - y) + f(i - 1, j, k)

这个题可以用i & 1来表示滚动数组,但是不能用二维的,因为x和y的是有正负的,不能保证在第i次的更新的时候下一次用不到他。

代码:

#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
using namespace std;
typedef long long ll;
typedef pair<int, int > PII;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int N = 1010;

int n;
ll f[2][N][N];

int main()
{
    
    
    scanf("%d", &n);

    f[0][500][500] = 1;

    for (int i = 1; i <= n; i++) {
    
    
        int x, y; scanf("%d%d", &x, &y);

        for (int j = 0; j <= 1000; j++) {
    
    
            for (int k = 0; k <= 1000; k++) {
    
    
                f[i & 1][j][k] = f[(i - 1) & 1][j][k];
                if (j >= x && k >= y)
                    f[i & 1][j][k] += f[(i - 1) & 1][j - x][k - y];
            }
        }
    }

    printf("%lld\n", f[n & 1][500][500] - 1);


    return 0;
}

Guess you like

Origin blog.csdn.net/YingShen_xyz/article/details/114332762
Recommended