ICPC North America Qualifier Contest 2015 D. Circuit Counting(dp)

Suppose you are given a sequence of NN integer-valued vectors in the plane (x_i,y_i)(xi​,yi​), i=1,\dots,Ni=1,…,N. Beginning at the origin, we can generate a path by regarding each vector as a displacement from the previous location. For instance, the vectors (1,2),(2,3),(−3,−5)(1,2),(2,3),(−3,−5) form the path (0,0),(1,2),(3,5),(0,0)(0,0),(1,2),(3,5),(0,0). We define a path that ends at the origin as a circuit. The example just given is a circuit. We could form a path using any nonempty subset of the NN vectors, while the result (circuit or not) doesn't depend on the ordering of the subset. How many nonempty subsets of the vectors form circuits?

For instance, consider the vectors \{(1,2),(−1,−2),(1,1),(−2,−3),(−1,−1)\}{(1,2),(−1,−2),(1,1),(−2,−3),(−1,−1)} From these vectors we can construct 44 possible subset circuits using

\left. \begin{array}{l} \{(1,2),(−1,−2)\}\\ \{(1,1),(−1,−1)\}\\ \{(1,2),(1,1),(−2,−3)\}\\ \{(1,2),(−1,−2),(1,1),(−1,−1)\} \end{array}\right.{(1,2),(−1,−2)}{(1,1),(−1,−1)}{(1,2),(1,1),(−2,−3)}{(1,2),(−1,−2),(1,1),(−1,−1)}​

 

Input

Input begins with an integer N\leq 40N≤40 on the first line. The next NN lines each contain two integer values xx and yyforming the vector (x,y)(x,y), where |x|,|y|\leq 10∣x∣,∣y∣≤10 and (x,y)\neq(0,0)(x,y)​=(0,0). Since the given vectors are a set, all vectors are unique.

Output

Output the number of nonempty subsets of the given vectors that produce circuits. It's guaranteed that the answer is less than 10^{10}1010.

输出时每行末尾的多余空格,不影响答案正确性

样例输入复制

5
1 2
1 1
-1 -2
-2 -3
-1 -1

样例输出复制

4

题意:

给出 n 组 (x, y)的值,问有多少种组合方式使得取出的所有(x, y)值的和为 (0, 0)

思路:

数据最大值是400,用dp[i][X][Y]表示前 i 个数对中选出若干个,和为(X, Y)的种类数。

状态转移方程:dp[i][X][Y] = dp[i - 1][X - x][Y - y] + dp[i - 1][X][Y]

有关滚动数组:https://blog.csdn.net/f_zyj/article/details/51478119

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int N = 1e3 + 10;

ll dp[2][N][N];

int main()
{
    int n, x, y;
    scanf("%d", &n);
    dp[1][500][500] = 1;
    for(int i = 0; i < n; ++i)
    {
        scanf("%d%d", &x, &y);
        for(int j = 0; j <= 1000; ++j)
        {
            for(int k = 0; k <= 1000; ++k)
            {
                dp[i & 1][j][k] = dp[(i & 1) ^ 1][j][k];
                if(j - x >= 0 && j - x <= 1000 && k - y >= 0 && k - y <= 1000)
                {
                    dp[i & 1][j][k] += dp[(i & 1) ^ 1][j - x][k - y];
                }
            }
        }
    }
    cout<<dp[(n & 1) ^ 1][500][500] - 1<<'\n';
    return 0;
}

 

全部评论

相关推荐

不愿透露姓名的神秘牛友
05-26 15:37
1、这群人晚上&nbsp;11&nbsp;点发朋友圈:"凌晨&nbsp;11&nbsp;点,三环的灯还亮着。"&nbsp;实际下班时间:19:30。2、什么是嘉豪呀?我最近在字节实习,没什么时间上网3、同龄人:学校社团、酒吧蹦迪;我:acm、字节/腾讯实习4、别人朋友圈发:“今天不想上课”;我朋友圈发:“今天的班就上到这里啦”,定位:字节跳动5、别人的朋友圈都是到处旅游的定位,我的朋友圈天天都是“字节定位”,还一定要是在【公司的健身房】里拍张照片,实际只练了10分钟,其中凹造型5分钟6、mentor布置任务的时候,别人都是:”好的收到“,我:”是不是要xxxx,xxxx这么做也可以吧,这个技术方案会不会更好些“7、别人书包里装的:王道408、轻薄本、四六级真题。我书包里面装的:显存24GB4090独显gpu(24小时开机运行,屏幕上贴着“字节/腾讯等贴纸”)、速效救心丸(代码报错用)、电棍(熬夜写代码困了用),就很……你们懂吧8、入职大厂第一件事:发朋友圈、发小红书,晒工牌,985计算机硕|字节实习生|可以接咨询|有偿改简历,9、别人的社交软件简介:25岁|男|希望遇见有趣的灵魂;嘉豪的社交软件简介:25岁|程序员|字节跳动工程师|一张佩戴工牌的自拍照大厂嘉豪标配:1.&nbsp;挂胸前的工牌(地铁里只挂不收,怕你看不见&nbsp;logo)2.&nbsp;降噪耳机(不放音乐也戴着,避免别人跟自己说话)3.&nbsp;印&nbsp;logo&nbsp;的电脑包(字节红&nbsp;/&nbsp;腾讯蓝&nbsp;/&nbsp;阿里橙&nbsp;/&nbsp;美团黄)4.&nbsp;手表(最好显示心率,午饭后必发"步数已破&nbsp;6,000")
布布永不言弃:可曾见过“我在未上市小厂实习,丢人了xxx”,然后接着说“这个小厂的创始人是张一鸣” 然后别人要是真不认识张一鸣 就直接急了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务