题目描述
这是一道和兔子有关的签到题:
かふうちの是一个可爱的初中生,虽然性格有些冷淡,但是不讨厌ココア…!?精通咖啡,并且能干可靠。
今天ちの在梦境中看见了一群野兔子,棉花糖般的兔子们每一只都有一个甜度 a i {a_i} ai 。ちの想从中挑选出一些兔子,使得它们的甜度和是 7 {7} 7 的倍数。请问能获得的最大甜度和是多少。
当然,这个问题可能太简单了,所以ココア降临了:ココア亲吻过的兔子会获得”祝福”,当ちの选择这只兔子之后,她将会减少 b i {b_i} bi点精神力。ちの最初有 H {H} H 点精神力,当精神力小于 0 {0} 0 时,她将会被ココア吃掉(((
ちの想知道怎么样才能完成挑选甜度和为 7 {7} 7 的倍数的兔子,甜度和最大的同时还不会被吃掉。
输入格式
第一行包含两个正整数
n
(
1
<
=
n
<
=
1
0
4
)
{n(1<=n<=10^4)}
n(1<=n<=104) 和
H
(
1
<
=
H
<
=
1
0
3
)
{H(1<=H<=10^3)}
H(1<=H<=103)。
第二行包含
n
{n}
n 个非负整数
a
i
(
0
<
=
a
i
<
=
1
0
9
)
{a_i(0<=a_i<=10^9)}
ai(0<=ai<=109),表示每只兔子的甜度。
第二行包含
n
{n}
n 个非负整数
b
i
(
0
<
=
b
i
<
=
10
)
{b_i(0<=b_i<=10)}
bi(0<=bi<=10) ,表示每只兔子对精神力的作用。
输出格式
输出单行,包含一个整数 S {S} S,表示挑选甜度和为 7 {7} 7 的倍数的兔子,且不会被吃掉的最大甜度和。
输入输出样例
输入 #1
10 10
9 3 7 3 6 4 4 5 9 9
0 1 1 1 1 0 0 1 0 0
输出 #1
56
输入 #2
3 10
4 3 4
6 5 5
输出 #2
7
有机会,补一下滚动数组的各类题型
-
f [ i ] [ j ] [ k ] {f[i][j][k]} f[i][j][k]
- i {i} i 表示当前状态或前一轮状态
- j {j} j 表示当前背包体积
- k {k} k 表示 % 7 {\%7} %7 的余数
-
转移方程(01背包):
- 不选 i {i} i : f [ n o w ] [ j ] [ k ] = f [ p r e ] [ j ] [ k ] {f[now][j][k] = f[pre][j][k]} f[now][j][k]=f[pre][j][k]
- 选 i {i} i : m a x ( f [ n o w ] [ j ] [ k ] , f [ p r e ] [ j − v [ i ] ] [ ( k + 7 − ( w [ i ] % 7 ) ) % 7 ] ) {max(f[now][j][k], f[pre][j-v[i]][(k + 7 - (w[i] \%7)) \%7] )} max(f[now][j][k],f[pre][j−v[i]][(k+7−(w[i]%7))%7])
#include<bits/stdc++.h>
// #include <bits/extc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define fi first
#define sz size()
#define se second
#define endl ('\n')
#define pb push_back
#define ll long long
#define int long long
#define vi vector<int>
#define eb emplace_back
#define lowbit(x) (x & -x)
#define PII pair<int, int>
#define pqu priority_queue<int>
#define vii vector<vector<int>>
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define pql priority_queue<int,vi,greater<int>>
#define rep(i,a,n) for(ll i = (a); i < (n); ++i)
#define Rep(i,a,n) for(ll i = (a); i <= (n); ++i)
#define lb(v,x) (lower_bound(all(v),x)-(v).begin())
#define ub(v,x) (upper_bound(all(v),x)-(v).begin())
#define Dbug(x) (cout << #x << " <=> " << x << endl)
#define IOS cin.tie(0), cout.tie(0), ios_base::sync_with_stdio(false);
#define print(x,s,e) { Rep(i,s,e) cout << x[i] << ' '; cout << endl; }
const int N = 250010;
const int mod = 1000000007;
using namespace std;
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
/*---------------------------------------------------------------------------------------------------------------------------*/
ll gcd(ll a, ll b){ if(b == 0){return a;} return gcd(b, a%b);}
ll lcm(ll a, ll b){ return (a * (b / gcd(a, b)));}
ll qmi(ll a, ll b){ if(!b) return 1ll; if(b&1) return a*qmi(a*a%mod, b>>1)%mod; return qmi(a*a%mod, b>>1)%mod;}
/*---------------------------------------------------------------------------------------------------------------------------*/
int n, m;
int w[N], v[N];
int f[2][1010][7];
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> w[i];
for (int i = 1; i <= n; i++) cin >> v[i];
memset(f, -1, sizeof f);
f[0][0][0] = f[1][0][0] = 0;
int pre = 0, now = pre ^ 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
for (int k = 0; k < 7; k++) {
f[now][j][k] = f[pre][j][k];
if(j >= v[i] && f[pre][j - v[i]][(k - (w[i] % 7) + 7) % 7] != -1)
f[now][j][k] = max(f[now][j][k], f[pre][j - v[i]][(k - (w[i] % 7) + 7) % 7] + w[i]);
}
}
now ^= 1, pre ^= 1;
// for (int j = 0; j <= m; j++)
// for (int k = 0; k < 7; k++)
// f[0][j][k] = f[1][j][k];
}
int res = 0;
for (int i = 0; i <= m; i++) res = max(res, max(f[0][i][0], f[1][i][0]));
cout << res << endl;
return ;
}
signed main() {
IOS int _ = 1;
// cin >> _;
while(_--) { solve(); }
return 0;
}