NOIP2006

传送门

https://vijos.org/p/1312
https://vijos.org/p/1313
https://vijos.org/p/1314
https://vijos.org/p/1315

T1 能量项链

题解

环形DP,变成2*n的线性,
a[i]..a[k],a[k+1]..a[j]
a[i]..a[k],合并后形成的新珠子的前后分别为a[i],a[k+1]
同理a[k+1]..a[j]的前后分别为a[k+1],a[j+1]
我们定义dp[i,j]为[i,j]段合并后的最大值
那么我们合并a[i]..a[k],a[k+1]..a[j]的结果为:
dp[i,k]+dp[k+1,j]+a[i]*a[k+1]*a[j+1]
我们得到转移方程:
dp[i,j]=max(dp[i,j],dp[i,k]+dp[k+1,j]+a[i]*a[k+1]*a[j+1])
注意转移方向

var
 dp:array[0..250,0..250]of longint;
 x:array[0..250]of longint;
 i,j,k:longint;
 n,ans:longint;
function max(a,b:longint):longint;
begin
 if a>b then exit(a) else exit(b);
end;

begin
 readln(n);
 for i:=1 to n do
  begin read(x[i]);  x[i+n]:=x[i]; end;
 fillchar(dp,sizeof(dp),0);
 for j:=2 to n do
  for i:=1 to 2*n do
   for k:=i to i+j-2 do
    dp[i,i+j-1]:=max(dp[i,i+j-1],dp[i,k]+dp[k+1,i+j-1]+x[i]*x[k+1]*x[i+j]);
 for i:=1 to n do
  ans:=max(ans,dp[i,i+n-1]); // writeln(dp[,n]);
 writeln(ans);
end.

T2 金明的预算方案

题目大意

给定购买物品的w[i],v[i]和它依附于谁
在最大花费m的范围内获得最大的w[i]*v[i]
w[i]都是10的倍数,某个物品的依附品个数不超过2个

题解

DP,从决策入手!从决策入手!从决策入手!
对于一个非依附品的物品,最多有三种决策
1.单独取它自己dp[j]:=max(dp[j],dp[j-w[i]]+w[i]*v[i])
2.如果有一个附属品,取它自己和它的附属品dp[j]:=max(dp[j],dp[j-w[i]-w[附属1]]+w[i]*v[i]+w[附属1]*v[附属1])
3.如果有两个附属品,分别取它自己和两个中一个,方程同上,或同时取它们三个

var
 x:array[0..100]of longint;
 sum:array[0..100,0..2]of longint;
 v,w:array[0..100]of longint;
 dp:array[0..3200]of longint;
 i,j,k:longint;
 n,m:longint;
 a,b,c:longint;
function max(a,b:longint):longint;
begin
 if a>b then exit(a) else exit(b);
end;

begin
 readln(m,n);
 for i:=1 to n do
  begin
   readln(v[i],w[i],x[i]);
   v[i]:=v[i] div 10;
   if x[i]<>0
   then begin inc(sum[x[i],0]); sum[x[i],sum[x[i],0]]:=i; end;
  end;
 m:=m div 10; dp[0]:=0;
 for i:=1 to n do
  begin
   if x[i]<>0 then continue;
   for j:=m downto v[i] do
    begin
     dp[j]:=max(dp[j],dp[j-v[i]]+v[i]*w[i]);
     if (sum[i,0]>0)and(j-v[i]-v[sum[i,1]]>=0)
     then dp[j]:=max(dp[j],dp[j-v[i]-v[sum[i,1]]]+v[i]*w[i]+v[sum[i,1]]*w[sum[i,1]]);
     if sum[i,0]>1 then begin
      if j-v[i]-v[sum[i,2]]>=0
      then dp[j]:=max(dp[j],dp[j-v[i]-v[sum[i,2]]]+v[i]*w[i]+v[sum[i,2]]*w[sum[i,2]]);
      if j-v[i]-v[sum[i,2]]-v[sum[i,1]]>=0
      then dp[j]:=max(dp[j],dp[j-v[i]-v[sum[i,2]]-v[sum[i,1]]]+v[i]*w[i]+v[sum[i,2]]*w[sum[i,2]]+v[sum[i,1]]*w[sum[i,1]]);
     end;
    end;
  end;
 writeln(dp[m]*10);
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值