poj 1260 Pearls

来源:互联网 发布:64位系统装32位mysql 编辑:程序博客网 时间:2024/05/21 17:04

用高一等级的代替低一等级的必须是连续代替。例如 3 5, 90 7, 100 12 要想代替3个5价值的首先考虑 用7价值的代替,因为 3*7=21 (3+10)* 5 =65 显然比较合算,这样就不需要考虑用12价值的那个代替了,因为前面已经有了最优解,也就是说相互代替不会跳跃。

证明这一点后开始分析,用sum[i]表示前i中珠宝总数,对于第i等级珠宝,ans[i]表示他的最优解,那么ans[i]可能是(sum[i]+10) *p[i] 即前面所有的珠宝用i的价值去买,或者(sum[i]-sum[1] +10 )*p[i] + ans[1] 即从第二个开始前面的所有珠宝用i的价值去买,或者(sum[i]-sum[2] +10)*p[i] + ans[2] 即从第三个。。。。。。。。依次计算,其中最小的一个就是i的解,这样

状态方程便有了 ans[i]=min(ans[i],(sum[i]-sum[j]+10)*p[i]+ans[j]) (1<=j<=i)

转自:

http://hi.baidu.com/bobo__bai/item/86dbf8267a50dd4647996208

#include <stdio.h>#include <iostream>#include <cstring>using namespace std;#define MAX_N (200)unsigned long A[MAX_N],P[MAX_N];unsigned long dp[MAX_N];int suma[MAX_N];int ans[MAX_N];int main(){int t;//while(cin>>t)cin>>t;{for(int _t = 1;_t <=t;_t++){int n;cin>>n;for(int i=1;i<=n;i++){cin>>A[i]>>P[i];suma[i] = suma[i-1]+A[i];}for(int i=1;i<=n;i++){int a=A[i];int p=P[i];ans[i] = (suma[i]+10) * p;for(int j=i-1;j>=1;j--){ans[i] = min(ans[i],(suma[i] - suma[j] +10) * p+ans[j]);}}cout<<ans[n]<<endl;}}}


自己写了份错误代码,有点类似于贪心性质,既i-1,i,i+1,尝试i-1与i换,能够换则换

下面举出反例:

1
3
10 2
1 3

1 5


正确结果为100,既1自己买,2,3合起来,以3的价值买


贪心则算出1,2,3一起以3的价格买,则为110,不是最优解。


原创粉丝点击