200.00 3 2 A:23.50 B:100.00 1 C:650.00 3 A:59.99 A:120.00 X:10.00 1200.00 2 2 B:600.00 A:400.00 1 C:200.50 1200.50 3 2 B:600.00 A:400.00 1 C:200.50 1 A:100.00 100.00 0
123.50 1000.00 1200.50
坑点:
注意题目中说的 “每项” 是指 每一种,不是每一个
方法1.直接sort(),不用dp,因为背包的每项所占的体积都是1
方法二:将报销的数额作为背包,将实数扩大100 倍。
方法3:
#include<bits/stdc++.h> using namespace std; double sum[10000],dp[10000]; int solve(char s[],double &l) //将字符串转化为实数 { int i=0; while(s[i]<'0'||s[i]>'9') i++; while(s[i]>='0'&&s[i]<='9') { l*=10; l+=s[i]-'0'; i++; } if(s[i]!='.') return 0; i++; double k=0.1; while(s[i]>='0'&&s[i]<='9') { l+= k*(s[i]-'0'); k*=0.1; i++; } } char s[1000000]; double a[10]; int main() { double v; int n; while(~scanf("%lf%d",&v,&n)) { if(n==0) break; for(int i=0;i<n;i++) { sum[i]=0; int m,flag=0; scanf("%d",&m); for(int i=0;i<3;i++) a[i]=0; for(int j=0;j<m;j++) { scanf("%s",s); //也可以通过scanf(" %c:%lf");进行处理输入问题 //就不必再有solve() // cout<<"#"<<s<<endl; if(flag) continue; int len=strlen(s); if(s[0]!='A'&&s[0]!='B'&&s[0]!='C') { sum[i]=0; flag=1; continue; } double l=0; solve(s,l); a[s[0]-'A']+=l; if(a[s[0]-'A']>600) //表示每一项 { flag=1; sum[i]=0; continue; } sum[i]+=l; if(sum[i]>1000) { flag=1; sum[i]=0; continue; } } } memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) { for(int j=n;j>=1;j--) //以支票个数为容量储存 { dp[j]=max(dp[j],dp[j-1]+sum[i]); } } double Max=0; for(int i=n;i>=0;i--) { if(dp[i]<=v&&Max<dp[i]) { Max=dp[i]; } } printf("%.2lf\n",Max); } }HDU1231
6 -2 11 -4 13 -5 -2 10 -10 1 2 3 4 -5 -23 3 7 -21 6 5 -8 3 2 5 0 1 10 3 -1 -5 -2 3 -1 0 -2 0
20 11 13 10 1 4 10 3 5 10 10 10 0 -1 -2 0 0 0
#include<bits/stdc++.h> using namespace std; int a[10010]; struct node { int l,r,num; }dp[10010]; int main() { int n; while(~scanf("%d",&n)) { if(n==0)break; for(int i=0;i<n;i++) { scanf("%d",&a[i]); dp[i].num=0; } // memset(dp,0,sizeof(dp)); dp[0].num=a[0]; dp[0].l=a[0]; dp[0].r=a[0]; for(int i=1;i<n;i++) { if(dp[i-1].num<=0) { dp[i-1].r=a[i-1]; dp[i].num=a[i]; dp[i].l=a[i]; } else { dp[i].l=dp[i-1].l; dp[i].num=dp[i-1].num+a[i]; dp[i].r=a[i]; } } int Max=0,flag=-1; for(int i=0;i<n;i++) { if(Max==dp[i].num&&Max==0) { Max=dp[i].num; flag=i; } else if(Max<dp[i].num) { Max=dp[i].num; flag=i; } } if(flag==-1) printf("0 %d %d\n",a[0],a[n-1]); else printf("%d %d %d\n",Max,dp[flag].l,dp[flag].r); } return 0; }
2 5 6 -1 5 4 -7 7 0 6 -1 1 -6 7 -5
Case 1: 14 1 4 Case 2: 7 1 6
#include<bits/stdc++.h> using namespace std; //数组开小了会TLE int a[100010]; struct node { int l,r,num; } dp[100010]; int main() {int n,Case=0,T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d",&a[i]); dp[i].num=0; } dp[0].num=a[0];dp[0].l=1;dp[0].r=1; for(int i=1;i<n;i++) { if(dp[i-1].num<0) { dp[i-1].r=i; dp[i].l=i+1; dp[i].num=a[i]; } else { dp[i-1].r=i; dp[i].r=i+1; dp[i].num=dp[i-1].num+a[i]; dp[i].l=dp[i-1].l; } } int Max=dp[0].num,flag=0; for(int i=1; i<n; i++) { if(Max<dp[i].num) { Max=dp[i].num; flag=i; } } if(Case!=0) printf("\n"); Case++; printf("Case %d:\n",Case); printf("%d %d %d\n",Max,dp[flag].l,dp[flag].r); } return 0; }