Uva 10306 e-Coins
题意:给定n个物品,每个物品有两个价值,x,y,问能否从中选择一些物品(数量任意),使得sum(x)^2+sum(y)^2==s*s
分析:二维费用的背包,dp[i][j]表示凑出两种费用分别为i,j的最小硬币数
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #define N 500 5 using namespace std; 6 const int inf=(1<<30); 7 int dp[N][N]; 8 int w1[N],w2[N]; 9 int main(){ 10 int t,m,s; 11 cin>>t; 12 while(t--){ 13 cin>>m>>s; 14 for(int i=1;i<=m;i++) 15 cin>>w1[i]>>w2[i]; 16 for(int j=0;j<N;j++) 17 for(int k=0;k<N;k++) 18 dp[j][k]=inf; 19 dp[0][0]=0; 20 for(int i=1;i<=m;i++) 21 for(int j=w1[i];j<N;j++) 22 for(int k=w2[i];k<N;k++) 23 dp[j][k]=min(dp[j][k],dp[j-w1[i]][k-w2[i]]+1); 24 int ans=inf; 25 for(int x=0;x<=s;x++) 26 for(int y=0;y<=s;y++){ 27 if(x*x+y*y!=s*s)continue; 28 if(dp[x][y]<inf) 29 ans=min(ans,dp[x][y]); 30 if(dp[y][x]<inf) 31 ans=min(ans,dp[y][x]); 32 } 33 if(ans<inf) 34 cout<<ans<<endl; 35 else 36 cout<<"not possible"<<endl; 37 } 38 return 0; 39 }