BNU - Soccer Teams- 01背包

13 篇文章 0 订阅
(1)1与0的特性:
1是任何整数的约数,即对于任何整数a,总有1|a.
0是任何非零整数的倍数,a≠0,a为整数,则a|0.

(2)若一个整数的末位是0、2、4、6或8,则这个数能被2整除。
(3)若一个整数的数字和能被3整除,则这个整数能被3整除。
(4) 若一个整数的末尾两位数能被4整除,则这个数能被4整除。
(5)若一个整数的末位是0或5,则这个数能被5整除。
(6)若一个整数能被2和3整除,则这个数能被6整除。
(7)若一个整数的个位数字截去,再从余下的数中,减去个位数的2倍,如果差是7的倍数,则原数能被7整除。如果差太大或心算不易看出是否7的倍数,就需要继续上述「截尾、倍大、相减、验差」的过程,直到能清楚判断为止。例如,判断133是否7的倍数的过程如下:13-3×2=7,所以133是7的倍数;又例如判断6139是否7的倍数的过程如下:613-9×2=595 , 59-5×2=49,所以6139是7的倍数,余类推。
(8)若一个整数的未尾三位数能被8整除,则这个数能被8整除。
(9)若一个整数的数字和能被9整除,则这个整数能被9整除。
(10)若一个整数的末位是0,则这个数能被10整除。
(11) 若一个整数的奇位数字之和与偶位数字之和的差能被11整除,则这个数能被11整除。11的倍数检验法也可用上述检查7的「割尾法」处理!过程唯一不同的是:倍数不是2而是1!
(12)若一个整数能被3和4整除,则这个数能被12整除。
(13)若一个整数的个位数字截去,再从余下的数中,加上个位数的4倍,如果差是13的倍数,则原数能被13整除。如果差太大或心算不易看出是否13的倍数,就需要继续上述「截尾、倍大、相加、验差」的过程,直到能清楚判断为止。
(14)若一个整数的个位数字截去,再从余下的数中,减去个位数的5倍,如果差是17的倍数,则原数能被17整除。如果差太大或心算不易看出是否17的倍数,就需要继续上述「截尾、倍大、相减、验差」的过程,直到能清楚判断为止。
(15)若一个整数的个位数字截去,再从余下的数中,加上个位数的2倍,如果差是19的倍数,则原数能被19整除。如果差太大或心算不易看出是否19的倍数,就需要继续上述「截尾、倍大、相加、验差」的过程,直到能清楚判断为止。
(16)若一个整数的末三位与3倍的前面的隔出数的差能被17整除,则这个数能被17整除。
(17)若一个整数的末三位与7倍的前面的隔出数的差能被19整除,则这个数能被19整除。

(18)若一个整数的末四位与前面5倍的隔出数的差能被23(或29)整除,则这个数能被23整除

还有简单的
能被7、13、11整除的特征(实际是一个方法)是这样的:
将一个多于4位的整数在百位与千位之间分为两截,形成两个数,左边的数原来的千位、万位成为个位、十位(依次类推)。
将这两个新数相减(较大的数减较小的数),所得的差不改变原来数能被7、11、13整除的特性。


这题用到能被11整除的性质,那我哪知道啊。然后就一直Orz,这是dp的代码。

void solve(){
    sum = 0;cnt = 0;
    for (int i = 1; i <= 9 ; ++i){
        cin >>a[i];
        sum += a[i] * i;// 和
        cnt += a[i];// 几个
    }
    memset(dp ,0 , sizeof(dp));
    
    
    dp[0][0] = 1;
    for (int x = 1 ; x <= 9 ; ++x){
        memset(use ,0 , sizeof(use));
        for (int i = 0 ; i < cnt ; ++i)
            for (int j = 0 ; j <= sum ; ++j){
                if (dp[i][j] && use[i][j] < a[x]){
                    dp[i + 1][j + x] = 1;
                    use[i + 1][j + x] = use[i][j] + 1;
                }
            }
    }
    int ans = 1000000;
    for (int i = 0 ; i < cnt ; ++i){
        for (int j = 0 ; j <= sum ; ++j){
            if (!dp[i][j]) continue;
            if (abs(sum - j - j) % 11) continue;
            ans = min(ans , max(abs(cnt - i - i) - 1 , 0));
        }
    }
    
    if (ans == 1000000) printf("-1\n");
    else printf("%d\n",ans+cnt);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值