2287: 【POJ Challenge】消失之物
首先我们有f[]表示所有物品都考虑时的方案数或者最大价值。
使用g[j]表示不选x物品时总重量为j的方案数或者价值最大值,就可以想出如何计算出不选x物品时的方案数或者最大价值了。
g[j]=f[j]-g[j-v]
(因为g[j-v]可以表示为刚好选了x的方案数)
#include
using namespace std;
typedef long long ll;
typedef pair pii;
typedef unsigned long long ull;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
const int maxn=2000+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int n,m;
int f[maxn],g[maxn];
int w[maxn];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&w[i]);
f[0]=1;
for(int i=1;i<=n;i++){
for(int j=m;j>=w[i];j--){
f[j]=(f[j]+f[j-w[i]])%10;
}
}
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
if(j
https://ac.nowcoder.com/acm/contest/140/E
也是用可撤销的套路,不过是对一棵子树撤销,还是有点厉害的
#include
using namespace std;
typedef long long ll;
typedef pair pii;
typedef unsigned long long ull;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
const int maxn=1e5+15;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
ll pow_mod(ll a,ll b){
ll ret=1;
while(b){
if(b&1)ret=ret*a%mod;
a=a*a%mod;
b>>=1;
}
return ret;
}
int n,m;
struct edge{
int to,nxt;
}e[maxn];
int head[maxn];
int tot;
void adde(int u,int v){
e[tot].to=v;
e[tot].nxt=head[u];
head[u]=tot++;
}
struct node{
ll d[11];
}dp[maxn];
node uni(node a,node b){
node ret=a;
for(int i=10;i>=2;i--){
for(int j=1;j=1;i--){
dp[line[i]]=disuni(dp[line[i]],dp[line[i-1]]);
}
ll t=b*pow_mod(val[a],mod-2)%mod;
for(int i=1;i<=10;i++)dp[a].d[i]=(dp[a].d[i]*t)%mod;
for(int i=1;i=1;i--){
dp[line[i]]=disuni(dp[line[i]],dp[line[i-1]]);
}
for(int i=2;i=2;i--){
dp[line[i]]=disuni(dp[line[i]],dp[line[i-1]]);
}
for(int i=1;i=1;i--){
ans=uni(disuni(dp[line[i]],dp[line[i-1]]),ans);
}
ans=uni(dp[a],ans);
printf("%lld\n",ans.d[b]);
}
}
return 0;
}
http://codevs.cn/problem/5429/
用单调队列优化背包,就是对每个余数分开做,然后维护单调递减的队列即可。
#include
using namespace std;
typedef long long ll;
typedef pair pii;
typedef unsigned long long ull;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
const int maxn=7000+15;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int n,m;
int v[maxn],w[maxn],c[maxn];
int dp[2][maxn];
pii que[maxn];
void work(int *f1,int *f2,int vv,int ww,int cc){
for(int b=0;bhead&&cnt.se>=que[tail-1].se)tail--;
que[tail++]=cnt;
while(k-que[head].fi>cc)head++;
f1[j]=que[head].se+k*ww;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&v[i],&w[i],&c[i]);
work(dp[i%2],dp[(i+1)%2],v[i],w[i],c[i]);
}
printf("%d\n",dp[n%2][m]);
return 0;
}